Promise 查缺补漏

2018-05-30  本文已影响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 })
  );
};

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 入门

上一篇下一篇

猜你喜欢

热点阅读