Promise



  • const promise = new Promise(function(resolve, reject) {
       //Promise构造函数接受一个函数作为参数,该函数接收两个参数
       //这两个参数由JS引擎提供,无需自己部署 
       if(/* 异步操作成功 */) {
         resolve(value);
       }
       else {
         reject(error);
       }
    })
    
    • resolve

      • Promise对象状态由pending变为fulfilled

      • 将异步操作的结果作为参数传出

      • resolve函数的参数还可能是一个promise实例

        const p1 = new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log(new Date());
            reject(new Error("p1 failed!!"));
          }, 2000);
        });
        
        const p2 = new Promise((resolve, reject) => {
          setTimeout(() => resolve(p1), 4000);
        });
        

        此时,p1的状态决定着p2的状态

    • reject

      • Promise对象状态由pending变为rejected
      • 将异步操作的报错作为参数传出

    then方法

    //then方法接受两个回调函数作为参数
    promise.then(function(value) {
      //第一个回调函数在对象状态变为resolved时调用
    }, function(error) {
      //第二个回调函数在对象状态变为rejected时调用
      //可选参数
    })
    

    两个函数接收的参数均为Promise对象传出的值

    其中,第二个函数是可选的

    Promise.prototype.then()

    then方法:为Promise实例添加状态改变时的回调函数

    then方法返回的是一个新的Promise实例(不是原来的实例),因此可以采用链式写法

    Promise.prototype.catch()

    • 该方法是.then(null, reject)then(undefined, reject)的别名,用于指定发生错误时的回调函数

    • 无论是异步操作发生的错误还是then方法指定的回调函数抛出的错误,都会被catch方法捕获

    • 如果没有使用catch方法指定错误处理的回调函数,Promise对象抛出的错误不会传递到外层代码,也就是Promise会“吃掉错误”

    • Node有一个unhandelRejection事件,专门监听未捕获的reject错误

    • const promise = new Promise(function (resolve, reject) {
        resolve('ok');
        setTimeout(function () { throw new Error('test') }, 0)
      });
      promise.then(function (value) { console.log(value) });
      

      上述代码再Promise运行结束后抛出了一个错误,即是在Promise函数体外抛出的,因此会冒泡到最外层被捕获

    • catch方法返回的也是一个promise对象

    Promise.prototype.finally()

    不管promise最后的状态是什么,在执行完then或者是catch回调函数以后,都会执行finally方法指定的回调函数

    <!--测了一下,好像在promise状态凝固了以后finally就直接执行了,-->

    finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

    finally本质上是then方法的特例。

    Promise.protoype.all()

    用于将多个Promise实例包装成一个新的Promise实例

    const p = Promise.all([p1, p2, p3]);
    
    • 参数:

      • Iterator接口
      • 返回的每个成员都是Promise实例
    • 新实例的状态

      • 当所有成员的状态变成fulfilled,新实例的状态也会变成fulfilled,此时将所有成员的返回值组成一个数组传给新实例的回调函数
      • 当有一个成员的状态为rejected,新实例的状态就变成rejected,第一个被reject的实例的返回值会被传给新实例的回调函数
    • 关于catch

      如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()catch方法。

      const p1 = new Promise((resolve, reject) => {
        resolve('hello');
      })
      .then(result => result)
      .catch(e => e);
      
      const p2 = new Promise((resolve, reject) => {
        throw new Error('报错了');
      })
      .then(result => result)
      .catch(e => e);
      
      Promise.all([p1, p2])
      .then(result => console.log(result))
      .catch(e => console.log(e));
      // ["hello", Error: 报错了]
      

      上面代码中,p1resolvedp2首先会rejected,但是p2有自己的catch方法,该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。

      如果p2没有自己的catch方法,就会调用Promise.all()catch方法。

    Promise.race()

    用于将多个Promise实例包装成一个新的Promise实例

    all()不同的是,只要有一个实例的状态改变了,新实例的状态就会随之改变

    接收参数:第一个改变的实例的返回值会被传给p的回调函数

    Promise.allSettled()

    用于将多个promise实例包装成一个新的Promise实例

    当所有的参数实例都返回结果后(无论成功还是失败),新实例才会结束

    新实例一旦结束,状态只会是fulfilled,不会变成rejected

    接收参数:

    Promise.any()

    用于将多个promise实例包装成一个新的Promise实例

    只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

    Promise.resolve()

    用于将对象转为Promise对象

    • Promise实例

      调用该函数将原封不动地返回实例

    • thenable对象

      一个具有then方法的对象

      • 将对象转成Promise对象
      • 立刻执行该对象的then方法
    • 不具有then方法的对象/不是对象

      • 返回一个新的Promise对象
      • 新对象状态为resolved
      • 参数传给回调函数
    • 无参数

      • 直接返回一个状态为resolvedPromise对象

    Promise.reject()

    Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

    const p = Promise.reject('出错了');
    // 等同于
    const p = new Promise((resolve, reject) => reject('出错了'))
    
    p.then(null, function (s) {
      console.log(s)
    });
    // 出错了
    

    上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。

    注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待