美文网首页
Promise 查缺补漏

Promise 查缺补漏

作者: 溪离欣洛 | 来源:发表于2018-05-30 10:05 被阅读7次

    promise 中 resolve 参数为一个 promise 时

    const p1 = new Promise(function (resolve, reject) {
      setTimeout(() => reject(new Error('fail')), 3000)
    })
    
    const p2 = new Promise(function (resolve, reject) {
      setTimeout(() => resolve(p1), 1000)
    })
    
    p2
      .then(result => console.log(result))
      .catch(error => console.log(error))
    

    p1是一个 Promise,3 秒之后变为rejected。p2的状态在 1 秒之后改变,resolve方法返回的是p1。由于p2返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。又过了 2 秒,p1变为rejected,导致触发catch方法指定的回调函数。

    Promise resolve 后代码依然执行

    Promise then 方法 返回为 Promise 时

    采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

    getJSON("/post/1.json").then(
      post => getJSON(post.commentURL)
    ).then(
      comments => console.log("resolved: ", comments),
      err => console.log("rejected: ", err)
    );
    

    Promise 吃掉错误

    对于没有捕获的 Promise 内部的错误,会在控制台输出 error 但是代码会继续执行,所谓的吃掉错误。

    const someAsyncThing = function() {
      return new Promise(function(resolve, reject) {
        // 下面一行会报错,因为x没有声明
        resolve(x + 2);
      });
    };
    
    someAsyncThing().then(function() {
      console.log('everything is great');
    });
    
    setTimeout(() => { console.log(123) }, 2000);
    // Uncaught (in promise) ReferenceError: x is not defined
    // 123
    

    node 中 process 上有一个 unhandleRejection 事件可以捕获未被捕获的 reject 。

    process.on('unhandledRejection', function (err, p) {
      throw err;
    });
    

    Promise catch

    catch 方法会捕获写在他之前的 then 方法里的错误和 Promise 错误。
    catch 方法中可以执行后会继续执行后面的 then 方法。
    如果没有错误将越过 catch 方法进入后续的 then 当中。
    catch 方法中可以抛出错误,错误将有后续的 catch 方法捕获, 如果没有 catch
    捕获则被吃掉。

    Promise 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 })
      );
    };
    
    • finally 只有回调函数一个参数
    • finally 方法不影响原有的 Promise 的返回值(上一个 resolve的内容就是返回值)

    Promise.resolve & Promise.reject

    Promise.resolve 和 Promise.reject 都会返回一个响应状态的 Promise 对象,都可以接收参数作为 resovle 和 reject 的内容,不同在于 Promise.resolve 对于有 then 方法的对象会特殊处理,会将 then 方法执行。

     let thenable = {
      then: function(resolve, reject) {
        resolve(42);
      }
    };
    
    let p1 = Promise.resolve(thenable);
    p1.then(function(value) {
      console.log(value);  // 42
    });
    

    参考&摘抄

    ECMAScript 6 入门

    相关文章

      网友评论

          本文标题:Promise 查缺补漏

          本文链接:https://www.haomeiwen.com/subject/ovhtsftx.html