promise 理解与总结

对Promise的理解

Promise是异步编程的一种解决方案,可以获取异步操作的消息,避免了地狱回调,它比传统的解决方案回调函数和事件更合理和更强大。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

(1)Promise的实例有三个状态:

  • pending(进行中)
  • fulfilled(已完成)
  • rejected(已拒绝)

(2)Promise的实例有两个过程

  • pending -> fulfilled : resolve()
  • pending -> rejected:rejecte()

特点:状态不受外界干;一旦状态改变,就不会再变,这也是promise这个名字的由来——“承诺”。

注意: 在构造 Promise 的时候,构造函数内部的代码是立即执行的。

状态的改变是通过 resolve() 和 reject() 函数来实现的,可以在异步操作结束后调用这两个函数改变 Promise 实例的状态,它的原型上定义了一个 then 方法,使用这个 then 方法可以为两个状态的改变注册回调函数。这个回调函数属于微任务,会在本轮事件循环的末尾执行。

Promise的缺点:

  • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

Promise的基本用法

(1)创建Promise对象

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject

它们是两个函数,调用后只是改变状态,并不会终结 Promise 的参数函数的执行。

const promise = new Promise(function(resolve, reject) {
  if (/* 异步操作成功 */){
    resolve(value);
    // 后续代码还可以继续执行
  } else {
    reject(error);
  }
});

一般情况下都会使用new Promise()来创建promise对象,但是也可以使用promise.resolvepromise.reject这两个方法。

这两种方法是new Promise的快捷形式,也创建一个promise对象。


 (2)Promise方法

  • then()

then方法是定义在promise原型对象上的,作用是为 Promise 实例添加状态改变时的回调函数。

promise.then(
    function(value){
        // 成功后执行的代码
    }, function(error){
        // 失败后执行的代码
    }
);

then方法可以接受两个回调函数作为参数,其中参数是可选的。

  • 第一个回调函数是Promise对象的状态变为resolved时调用;
  • 第二个回调函数是Promise对象的状态变为rejected时调用。

then方法返回的是一个新的Promise实例。因此可以采用链式写法,在then后再调用then方法。

  • catch()

Promise对象还有一个catch方法,该方法相当于then方法的第二个参数,指向reject的回调函数。在执行resolve回调函数时,如果出现错误,不会停止运行,而是进入catch方法中。

p.then((data) => {
     console.log('resolved',data);
    },(err) => {
     console.log('rejected',err);
     }
); 
p.then((data) => {
    console.log('resolved',data);
}).catch((err) => {
    console.log('rejected',err);
});
  • finally()

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

上面代码中,不管promise最后的状态,在执行完thencatch指定的回调函数以后,都会执行finally方法指定的回调函数。

finally方法的回调函数不接受任何参数,这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。finally本质上是then方法的特例:

promise.then(
  result => {
    // 语句
    return result;
  },
  error => {
    // 语句
    throw error;
  }
);

使用finally方法,同样的功能,就不需要为成功和失败两种情况各写一次。

  • all()

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

它接收一个数组,数组的每一项都是一个promise对象。当数组中所有的promise的状态都达到resolved的时候,all方法的状态就会变成resolved,如果有一个状态变成了rejected,那么all方法的状态就会变成rejected

let promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
       resolve(1);
    },2000)
});
let promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
       resolve(2);
    },1000)
});
let promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
       resolve(3);
    },3000)
});
Promise.all([promise1,promise2,promise3]).then(res=>{
    console.log(res);
    //结果为:[1,2,3] 
})

调用all方法时的结果成功的时候是回调函数的参数也是一个数组,这个数组按顺序保存着每一个promise对象resolve执行时的值。失败的时候,返回失败对象执行reject的值。

  • race()

race方法和all一样,接受的参数是一个每项都是promise的数组,但是与all不同规则是,当最先执行完的事件执行完之后,就直接返回该promise对象的值。如果第一个promise对象状态变成resolved,那自身的状态变成了resolved;反之第一个promise变成rejected,那自身状态就会变成rejected

let promise1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
       reject(1);
    },2000)
});
let promise2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
       resolve(2);
    },1000)
});
let promise3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
       resolve(3);
    },3000)
});
Promise.race([promise1,promise2,promise3]).then(res=>{
    console.log(res);
    //结果:2
},rej=>{
    console.log(rej)};
)
posted @ 2021-10-02 22:05  辉太狼`  阅读(135)  评论(0编辑  收藏  举报