zoukankan      html  css  js  c++  java
  • ES6知识点整理之----Primise----API

    Promise.prototype.then()

    作用是为 Promise 实例添加状态改变时的回调函数。返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

    getJSON("/posts.json").then(function(json) {
      return json.post;
    }).then(function(post) {
      // ...
    });

    getJSON("/post/1.json").then(function(post) { return getJSON(post.commentURL); }).then(function (comments) { console.log("resolved: ", comments); }, function (err){ console.log("rejected: ", err); });

    第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

    第一个回调函数返回一个Primise对象时,后一个回调函数就会等待该Promise对象状态发生变化才会被调用。

    Promise.prototype.catch()

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

    getJSON('/posts.json').then(function(posts) {
      // ...
    }).catch(function(error) {
      // 处理 getJSON 和 前一个回调函数运行时发生的错误
      console.log('发生错误!', error);
    });
    // catch方法会捕获 getJSON抛出的错误,也会捕获then指定的回调函数抛出的错误

    Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

    getJSON('/post/1.json').then(function(post) {
      return getJSON(post.commentURL);
    }).then(function(comments) {
      // some code
    }).catch(function(error) {
      // 处理前面三个Promise产生的错误
    });

    一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。原因是catch方法总是可以捕获then方法中的错误,并且也更接近于同步的写法

     跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。

    Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。

    一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误。catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。如果没有报错,则会跳过catch方法。

    catch方法之中,还能再抛出错误。

    Promise.prototype.finally()

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

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

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

    finally方法的回调函数不接受任何参数,里面的操作与状态无关,不依赖于 Promise 的执行结果。

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

    finally方法总是会返回原来的值。

    finally方法的实现:

    Promise.prototype.finally = function (callback) {
      let P = this.constructor;
      return this.then(
        value  => P.resolve(callback()).then(() => value),
        reason => P.resolve(callback()).then(() => { throw reason })
      );
    };

    Promise.all()

    用于将多个 Promise 实例,包装成一个新的 Promise 实例。接受一个数组作为参数,数组成员为Promise实例。如果不是,会先调用Promise.resolve方法,将参数转为Promise实例。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

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

    p的状态由p1p2p3决定,分成两种情况:

    • 只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。
    • 只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

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

    Promise.race()

    同样是将多个 Promise 实例,包装成一个新的 Promise 实例。参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。

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

    只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    Promise.allSettled()

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

    该方法返回的新的 Promise 实例,一旦结束,状态总是fulfilled,不会变成rejected。状态变成fulfilled后,Promise 的监听函数接收到的参数是一个数组,每个成员对应一个传入Promise.allSettled()的 Promise 实例。

    const resolved = Promise.resolve(42);
    const rejected = Promise.reject(-1);
    
    const allSettledPromise = Promise.allSettled([resolved, rejected]);
    
    allSettledPromise.then(function (results) {
      console.log(results);
    });
    // [
    //    { status: 'fulfilled', value: 42 },
    //    { status: 'rejected', reason: -1 }
    // ]
    
    //Promise.allSettled()的返回值allSettledPromise,状态只可能变成fulfilled。
    //它的监听函数接收到的参数是数组results。该数组的每个成员都是一个对象,对应传入Promise.allSettled()的两个 Promise 实例。
    //每个对象都有status属性,该属性的值只可能是字符串fulfilled或字符串rejected。fulfilled时,对象有value属性,rejected时有reason属性,对应两种状态的返回值。

    Promise.allSettled()方法不关心异步操作的结果,只关心这些操作有没有结束(确保所有操作都结束),Promise.all()方法无法做到这一点。

    Promise.any()

    该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

    Promise.any()Promise.race()方法很像,只有一点不同,就是不会因为某个 Promise 变成rejected状态而结束。

    var resolved = Promise.resolve(42);
    var rejected = Promise.reject(-1);
    var alsoRejected = Promise.reject(Infinity);
    
    Promise.any([resolved, rejected, alsoRejected]).then(function (result) {
      console.log(result); // 42
    });
    
    Promise.any([rejected, alsoRejected]).catch(function (results) {
      console.log(results); // [-1, Infinity]
    });

    Promise.resolve()

    将现有对象转为 Promise 对象。

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

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

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

    参数分成四种情况:

    • 参数是一个 Promise 实例:将不做任何修改、原封不动地返回这个实例。
    • 参数是一个thenable对象:thenable对象指的是具有then方法的对象,将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
    • 参数不是具有then方法的对象,或根本就不是对象:返回一个新的 Promise 对象,状态为resolved
    • 不带有任何参数:直接返回一个resolved状态的 Promise 对象。需要注意的是,立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。

    Promise.reject()

    返回一个新的 Promise 实例,该实例的状态为rejected

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

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

    Promise.try()

    让同步函数同步执行,异步函数异步执行,并且让它们具有统一的 API。

    其他变通的两种方法如下:

    方法一:async函数。注意,async () => f()会吃掉f()抛出的错误,要使用primise.catch方法捕获。

    const f = () => console.log('now');
    (async () => f())().then(...).catch(...);
    console.log('next');
    // now
    // next

    方法二:new Promise()。

    const f = () => console.log('now');
    (
      () => new Promise(
        resolve => resolve(f())
      )
    )();
    console.log('next');
    // now
    // next

    使用Promise.try方法代替以上两种写法:

    const f = () => console.log('now');
    Promise.try(f);
    console.log('next');
    // now
    // next

    事实上,Promise.try就是模拟try代码块,就像promise.catch模拟的是catch代码块。

    Promise.try(database.users.get({id: userId}))
      .then(...)
      .catch(...)
  • 相关阅读:
    网络基础、多线程、ftp任务铺垫
    文件上传下载、socketserver(并发)、解读socketserver源码
    模拟ssh、黏包、hashlib模块(MD5)
    面向对象多继承(C3算法)/网络编程
    Slideout吐槽
    HDU 1756 Cupid's Arrow 判断点在多边形的内部
    POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,判断点在凸多边形内
    位运算 找出给定的数中其他数都是两个,有两个是一个的数
    NYOJ 1107 最高的奖励(贪心+优先队列)
    POJ 2653 Pick-up sticks (判断线段相交)
  • 原文地址:https://www.cnblogs.com/adhehe/p/9678967.html
Copyright © 2011-2022 走看看