Promise

Promise

1.认识Promise

Promise是异步操作的一种解决方法

回调函数

 document.addEventListener('click', () => {
      console.log("这里是异步的!");

    });
    console.log("这里是同步的!");

2.什么时候使用Promise

Promise一般用来解决层层嵌套的回调函数(回调地狱callback hell)的问题

3.Promise的基本用法

3.1 实例化构造函数生成实例化对象

Promise解决的不是回调函数,而是回调地狱

const p = new Promise(()=>{});

3.2 Promise的状态

Promise的状态一旦变化,就不会再改变了

Promise有三种状态,一开始是pending(未完成),执行resolve,变成fulfilled(resolved),已成功,执行reject,变成rejected,以失败

  const p = new Promise((resolve, reject) => {
      
      //pending->fulfilled
      // resolve();
      //pending->rejected
      //reject();
    });
    console.log(p);
    

3.3 then方法

3.3.1什么时候执行

pending-->fulfilled时,执行then的第一个回调函数
pending-->rejected时,执行then的第二个回调函数

3.3.2 执行后的返回值

then方法执行后返回一个新的Promise对象

3.3.3 then方法返回的Promise对象的状态改变

const p = new Promise((resolve,reject)=>{
      reject();
    });
    p.then(()=>{
       console.log('success');
       
    },()=>{
      console.log('err'); //err
      //在then的回调函数中,return后面的东西,会用Promise包装一下
      return 123;
      //等价于
      // return new Promise((resolve,reject)=>{
      //    //默认情况下就调用resolve,默认返回的永远是成功状态的Promise对象
      //   resolve(123);
      // })
        
        //如果想要返回失败的的状态,就手动写完整
        //return new Promise((resolve,reject)=>{
     //  reject(123);
      })
    }).then((data)=>{
      console.log('success2',data); // success2 123
    },(err)=>{
      console.log('err2',err); //err2 123
    })
    const p = new Promise((resolve, reject) => {
      resolve();
      // reject();
    });
p.then(()=>{
      console.log('success'); //success
      
    },()=>{
      console.log('error');
    })

3.4resolve和reject函数的参数

 // 执行成功
    const p = new Promise((resolve, reject) => {
        //resole('succ');
        resolve({username:'LiHao'});
      // reject();
    });
    p.then((data)=>{
      console.log('success',data); //success {username: "LiHao"}
      
    },()=>{
      console.log('error');
    });
//执行失败
 const p = new Promise((resolve, reject) => {
      // resolve({username:'LiHao'});
      reject(new Error('reason'));
    });
    p.then((data)=>{
      console.log('success',data);
      
    },(err)=>{
      console.log('error',err); // error Error: reason
    })

4.catch()

4.1catch()有什么用

catch专门用来处理rejected状态

catch本质上是then的特例

4.2基本用法

 //catch()可以捕获它前面的错误
//一般总是建议,Promise对象后面要跟catch()方法,这样可以处理Promise内部发生的错误
new Promise((resolve, reject) => {
      // resolve(123);
      reject('reason')
    }).then(data => {
      console.log(data);

    }).catch(err => {
      console.log(err);

    })

5.finally()方法

5.1什么时候执行

当Promise状态发生变化时,不论如何变化都会执行,不变化不执行
 new Promise((resolve,reject)=>{
        // resolve(123)
        reject('reason');
    }).finally(data=>{
      console.log(data); //undfined
    }).catch(err=>{})

5.2本质

finally()本质上是then()的特例

6.Promise.resolve()和Promise.reject()

6.1 Promise.resolve()是成功状态Promise的一种简写形式

new Promise(resolve=>resolve('foo'));//简写Promise.resolve('foo');//参数//一般参数Promise.resolve('foo').then(data=>{      console.log(data);//foo         })
  const p1 = new Promise(resolve=>{      setTimeout(resolve,1000,'我执行了');      //等价于      // setTimeout(()=>{      //   resolve('我执行了');      // },1000);    })    Promise.resolve(p1).then(data=>{      console.log(data);//一秒之后执行,打印'我执行了'    })	//等价于    p1.then(data=>{        console.log(data);    });	console.log(Promise.resolve(p1)===p1)//true
当resolve函数接收的是Promise对象时,后面的then会根据传递的Promise对象的状态变化决定执行哪一个回调
//概括就是 这个then是否执行是由p1的状态来决定的new Promise(resolve => resolve(p1).then(data=>{	console.log(data); //我执行了}))
具有then方法的对象
 const thenable = {      then(resolve, reject) {        console.log('then'); //then        resolve('data');        // reject('reason');      }    };    Promise.resolve(thenable).then(data => console.log(data), err => console.log(err) //data    )

6.2Promise.reject()是失败状态Promise的一种简写形式

new Promise(reject=>reject('reason'));//简写Promise.reject('freason');//参数//不管什么参数,都会原封不动地向后传递,作为后续方法的参数 

7.Promise.all()

7.1有什么用

Promise.all()关注多个Promise对象的状态变化

传入多个Promise实例,包装成一个新的Promise实例返回

7.2基本用法

Promise.all()的状态变化为所有传入的Promise实例对象状态有关
所有状态都变成resolved,最终的状态才会变成resolved
只要有一个变成rejected,最终的状态就变成rejected
const delay = ms => {      return new Promise(resolve => {        setTimeout(resolve, ms);      })    }    const p1 = delay(1000).then(() => {      console.log('p1完成了');      return 'p1';    });    const p2 = delay(2000).then(() => {      console.log('p2完成了');      return 'p2';    });    const p = Promise.all([p1, p2]);    p.then(data => {      console.log(data);    }, err => {      console.log(err);    })

8.Promise.race()和Promise.allSettled()

8.1Promise.race()

Promise.race()的状态取决于第一个完成的Promise实例对象,如果第一个完成的成功了,那最终就是成功,如果第一个完成的失败了,那最终的就失败
  const delay = ms => {      return new Promise(resolve => {        setTimeout(resolve, ms);      })    }    const p1 = delay(1000).then(() => {      console.log('p1完成了');      return 'p1';    });    const p2 = delay(2000).then(() => {      console.log('p2完成了');      return 'p2';    });    const racePromise = Promise.race([p1, p2]);    racePromise.then(data => {      console.log(data); // p1  只跟第一个有关    }, err => {      console.log(err);    })

8.2Promise.allSettled()

Promise.allSettled()的状态与传入的Promise状态无关,永远都是成功的,它只会忠实的记录下各个Promise的表现
 const delay = ms => {      return new Promise(resolve => {        setTimeout(resolve, ms);      })    }    const p1 = delay(1000).then(() => {      console.log('p1完成了');      // return 'p1';      return Promise.reject('err');    });    const p2 = delay(2000).then(() => {      console.log('p2完成了');      return 'p2';    });    const allSettledPromise = Promise.allSettled([p1, p2]);    allSettledPromise.then(data => {      console.log(data);    }, err => {      console.log(err);    })

9.Promise的注意事项

9.1resolve或reject函数执行后的代码

推荐在调用resolve或reject函数的时候加上return,不再执行他们后面的代码

9.2Promise.all/race/allSettled的参数问题

参数如果不是Promise数组,会将不是Promise的数组元素转变成Promise对象

  Promise.all([1,2,3]).then(data=>{      console.log(data); //[1,2,3]    });    //等价于    Promise.all([      Promise.resolve(1),      Promise.resolve(2),      Promise.resolve(3)    ]).then(data=>{      console.log(data); //[1, 2, 3]        })//不只是数组,任何可遍历的都可以作为参数//数组、字符串、Set、Map、arguments、NodeList

10.Promise的应用

异步加载图片

<img  id='img' src="https://images.pexels.com/photos/7647498/pexels-photo-7647498.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" alt="">    <script>        const loadImgAsync = url => {            return new Promise((resolve, reject) => {                const img = new Image();                img.onload = () => {                    resolve(img);                };                img.onerror = ()=>{                    reject(new Error(`Could not load image at ${url}`));                };                img.src = url;            });        };        const imgDOM = document.getElementById('img');        loadImgAsync('https://images.pexels.com/photos/8066135/pexels-photo-8066135.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500').then(img=>{                console.log(img.src);                imgDOM.addEventListener('click',()=>{                    imgDOM.src = img.src;                },false)                                        }).catch(err=>{            console.log(err);                    })    </script>
posted @ 2021-06-01 21:48  平平无奇小乐一  阅读(91)  评论(0编辑  收藏  举报