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
});
参考&摘抄
网友评论