Promise对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为Promise内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
asyncFunc()
.then(f1)
.catch(r1)
.then(f2)
.done();
示例 :
var p1 = new Promise(function(resolve, reject){
setTimeout(()=>{
resolve(1);
}, 1000);
});
var p2 = new Promise(function(resolve, reject){
setTimeout(()=>{
reject("error 0001");
}, 500);
});
let p = Promise.all([p1,p2]);
Promise.prototype.done = function (onFulfilled, onRejected) {
this.then(onFulfilled, onRejected)
.catch(function (reason) {
// 抛出一个全局错误
throw reason;
});
};
p.then(function(res){
console.log(res);
}).catch(function(e){
console.log(e);
});
从上面代码可见,done方法的使用,可以像then方法那样用,提供Fulfilled和Rejected状态的回调函数,也可以不提供任何参数。但不管怎样,done都会捕捉到任何可能出现的错误,并向全局抛出。
finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。
var p1 = new Promise(function(resolve, reject){
setTimeout(()=>{
resolve(1)
}, 1000);
});
var p2 = new Promise(function(resolve, reject){
setTimeout(()=>{
resolve(2)
}, 500);
});
let p = Promise.all([p1,p2]);
p.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};
p.then(function(res){
console.log(res);
}).catch(function(e){
console.log(e);
}).finally(function(){
console.log("finally");
});