• ES6


     1.Promise.prototype.finally()

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

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

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

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

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

     上面代码中,如果不使用finally方法,同样的语句需要成功和失败各写一次。finally方法只需要写一次

    finally的实现:

    1     Promise.prototype.finally = function (callback) {
    2         let p = this.constructor
    3         return this.then(
    4             value => p.resolve(callback()).then(() => value),
    5             reason => p.resolve(callback()).then(() => { throw reason })
    6         )
    7     }

    上面代码中,不管前面的Promise是fulfilled还是rejected,都会执行回调函数callback

    从上面的实现还可以看到,finally方法总是会返回原来的值。

     1 // resolve 的值是 undefined
     2 Promise.resolve(2).then(() => {}, () => {})
     3 
     4 // resolve 的值是 2
     5 Promise.resolve(2).finally(() => {})
     6 
     7 // reject 的值是 undefined
     8 Promise.reject(3).then(() => {}, () => {})
     9 
    10 // reject 的值是 3
    11 Promise.reject(3).finally(() => {})

    2.Promise.all()

    此方法用于将多个Promise实例,包装成一个新的Promise实例。

    只有所有的异步操作的状态都变成fulfilled或者其中一个变成了rejected,才会调用Promise.all方法后面的回调函数。

     1     const p1 = new Promise((resolve, reject) => {
     2         setTimeout(() => {
     3             resolve("p1执行结束")
     4         }, 1000)
     5     })
     6 
     7     const p2 = new Promise((resolve, reject) => {
     8         setTimeout(() => {
     9             resolve("p2执行结束")
    10         }, 3000)
    11     })
    12 
    13     const p3 = new Promise((resolve, reject) => {
    14         setTimeout(() => {
    15             resolve("p3执行结束")
    16         }, 2000)
    17     })
    18 
    19     const p = Promise.all([
    20         p1,
    21         p2,
    22         p3
    23     ])
    24 
    25     p.then(res => console.log(res))  // ["p1执行结束", "p2执行结束", "p3执行结束"]

    上面的代码中,有三个异步操作,只有在三个异步的状态都变成了了resolved,then()方法才会返回所有异步操作的结果。如果有一个状态变成了rejected。则错误会被catch捕获到:

     1     const p1 = new Promise((resolve, reject) => {
     2         setTimeout(() => {
     3             resolve("p1执行结束")
     4         }, 1000)
     5     })
     6 
     7     const p2 = new Promise((resolve, reject) => {
     8         setTimeout(() => {
     9             resolve("p2执行结束")
    10         }, 3000)
    11     })
    12 
    13     const p3 = new Promise((resolve, reject) => {
    14         setTimeout(() => {
    15             reject("p3执行失败")
    16         }, 2000)
    17     })
    18 
    19     const p = Promise.all([
    20         p1,
    21         p2,
    22         p3
    23     ])
    24 
    25     p.then(res => console.log(res))
    26         .catch(err => console.log("抛出错误:", err))  // 抛出错误: p3执行失败

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

     1     const p1 = new Promise((resolve, reject) => {
     2         resolve('hello');
     3     })
     4         .then(result => result)
     5         .catch(e => e);
     6 
     7     const p2 = new Promise((resolve, reject) => {
     8         throw new Error('报错了');
     9     })
    10         .then(result => result)
    11         .catch(e => e);
    12 
    13     Promise.all([p1, p2])
    14         .then(result => console.log(result))
    15         .catch(e => console.log("------",e));
    16     // ["hello", Error: 报错了]

    3.Promise.race()

    Promise.race()方法同样是将多个Promise实例,包装成一个新的Promise实例

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

    上面代码种,只要p1,p2,p3种有一个实例率先改变状态,p的状态就改变。那个最先改变的Promise实例的返回值,就传递给p的回调函数。

     1     const p1 = new Promise((resolve, reject) => {
     2         setTimeout(() => {
     3             resolve("p1执行结束")
     4         }, 6000)
     5     })
     6 
     7     const p2 = new Promise((resolve, reject) => {
     8         setTimeout(() => {
     9             resolve("p2执行结束")
    10         }, 3000)
    11     })
    12 
    13     const p3 = new Promise((resolve, reject) => {
    14         setTimeout(() => {
    15             resolve("p3执行结束")
    16         }, 2000)
    17     })
    18 
    19     const p = Promise.race([
    20         p1,
    21         p2,
    22         p3
    23     ])
    24 
    25     p.then(res => console.log(res))  // p3执行结束

    上面代码中,最先执行结束的p3的结果会传递到then中的回调函数中。

    4.Promise.allSettled()

    Promise.allSettled()方法接受一组Promise实例作为参数,包装成一个新的Promisee实例。等到所有这些实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。

    示例:

     1     const p1 = new Promise((resolve, reject) => {
     2         setTimeout(() => {
     3             resolve("p1执行结束")
     4         }, 6000)
     5     })
     6 
     7     const p2 = new Promise((resolve, reject) => {
     8         setTimeout(() => {
     9             reject("p2执行结束")
    10         }, 3000)
    11     })
    12 
    13     const p3 = new Promise((resolve, reject) => {
    14         setTimeout(() => {
    15             resolve("p3执行结束")
    16         }, 2000)
    17     })
    18 
    19     const p = Promise.allSettled([
    20         p1,
    21         p2,
    22         p3
    23     ])
    24 
    25     p.then(res => console.log(res))  
    26     /*
    27     0: {status: "fulfilled", value: "p1执行结束"}
    28     1: {status: "rejected", reason: "p2执行结束"}
    29     2: {status: "fulfilled", value: "p3执行结束"}
    30
    Promise.settled执行结束
    31     */

     结果:异步时间最长(6s)的异步操作p1执行结束以后,打印出了异步执行的结果(都包含了状态<status>,和结果以及rejected时的reason)。这里无论单个Promise的状态是变成fulfilled还是rejected,都会等所有的状态变为最终状态。

    且:一旦结束,状态总是fulfilled。不会变成rejected。所以后面可以接then。继续执行

     与Promise.all()的区别:

    • Promise.all()需要等到所有的状态都变成resolved或者某一个变成rejected才会返回
    • 有时候,不关心异步操作的结果,只关心这些操作有没有结束。这一点Promise.allSettled()就比较实用

    5.Promise.any()

    该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。

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

     示例一:所有异步都变成rejected:

     1     const p1 = new Promise((resolve, reject) => {
     2         setTimeout(() => {
     3             reject("p1执行结束失败")
     4         }, 6000)
     5     })
     6 
     7     const p2 = new Promise((resolve, reject) => {
     8         setTimeout(() => {
     9             reject("p2执行失败")
    10         }, 3000)
    11     })
    12 
    13     const p3 = new Promise((resolve, reject) => {
    14         setTimeout(() => {
    15             reject("p3执行失败")
    16         }, 2000)
    17     })
    18 
    19     const p = Promise.any([
    20         p1,
    21         p2,
    22         p3
    23     ])
    24 
    25     p.then(res => {
    26         console.log("any执行结束", res)
    27     })
    28         .then(() => {
    29             console.log("Promise.settled执行结束");
    30         })
    31         .catch(err => {
    32             console.log("所有异步均失败", err);
    33         })
    34 
    35     // 6s后: 所有异步均失败 AggregateError: All promises were rejected

     示例二:一个异步变成fulfilled:

     1     const p1 = new Promise((resolve, reject) => {
     2         setTimeout(() => {
     3             resolve("p1执行结束")
     4         }, 6000)
     5     })
     6 
     7     const p2 = new Promise((resolve, reject) => {
     8         setTimeout(() => {
     9             resolve("p2执行结束")
    10         }, 3000)
    11     })
    12 
    13     const p3 = new Promise((resolve, reject) => {
    14         setTimeout(() => {
    15             resolve("p3执行结束")
    16         }, 2000)
    17     })
    18 
    19     const p = Promise.any([
    20         p1,
    21         p2,
    22         p3
    23     ])
    24 
    25     p.then(res => {
    26         console.log("any执行结束", res)
    27     })
    28         .then(() => {
    29             console.log("Promise.settled执行结束");
    30         })
    31         .catch(err => {
    32             console.log("所有异步均失败", err);
    33         })
    34 
    35     // 2s后:
    36     // - any执行结束 p3执行结束
    37     // - Promise.settled执行结束

    6.Promise.resolve()

    有时候需要将现有对象转为Promise对象,Promise.resolve()就是这个作用。

    如:

    const jsPromise = Promise.resolve($.ajax('/whatever.json'));

    上面代码将jQuery生成的deferred对象,转为一个新的Promise对象。

    Promise.resolve()等价于下面的写法:

        Promise.resolve("foo")
        // 等价于
        new Promise(resolve => resolve("foo"))

    Promise.resolve()方法的参数有四种情况:

    (1)参数是一个Promise对象

      那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

    (2)参数是一个thenable对象

      thenable对象指的是具有then方法的对象,如下面这个对象:

    let thenable = {
        then: function(resolve,reject){
            resolve(123)
        }
    }

    Promise.resolve()方法会将这个对象转为Promise对象,然后立即执行thenable对象的then ()方法。

     1     let thenable = {
     2         then: function (resolve, reject) {
     3             resolve(123)
     4         }
     5     }
     6 
     7     let p1 = Promise.resolve(thenable)
     8     p1.then(function (value) {
     9         console.log(value);  // 123
    10     })

    上面代码中,thenable对象的then()方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then()方法指定的回调函数,输出42

    (3)参数不是具有then()方法的对象,或者根本不是对象。

      如果参数是一个原始值,或者是一个不具有then()方法的对象,则Promise.resolve()方法返回一个新的 Promise 对象,状态为resolved

    1     const p = Promise.resolve('Hello');
    2 
    3     p.then(function (s) {
    4         console.log(s)
    5     });
    6     // Hello

    上面代码生成一个新的 Promise 对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise 实例的状态从一生成就是resolved,所以回调函数会立即执行。Promise.resolve()方法的参数,会同时传给回调函数。

    (4)没有任何参数

    Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的Promise对象。所以,如果希望得到一个Promise对象,比较方便的方法就是直接调用Promise.resolve()方法。

    const p = Promise.resolve();
    
    p.then(function () {
      // ...
    });

     7.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)
    });
    // 出错了

     8.Promise.try()

  • 相关阅读:
    倒排索引压缩
    记一次java内存溢出的解决过程
    [译]ES读写文档时shard-replication模型
    [转载]抓包工具Charles乱码解决办法
    Mac 快捷键整理(不定期更新)
    高效能人士执行的四原则(2017-12-15)
    scala sbt 添加国内镜像
    maven工程小红叉处理方法
    系统管理中 bash shell 脚本常用方法总结
    scala 2.11报错error: not found: type Application
  • 原文地址:https://www.cnblogs.com/codexlx/p/14362816.html
Copyright © 2020-2023  润新知