背景
今天在一个技术群里被问到 Promise 中 .then 的第二个参数与 .catch有什么区别? 在我的脑海里,catch是这样用的
var p = new Promise(function (resove, reject){
throw new Error('hehe');
})
p.then(function success(e){
console.log(e);
}, function fail(e){
console.log(e);
}).catch(function (e){
console.log(e); // 认为这里会打印hehe,是一个兜底处理异常的方式
})
其实不是的,promise作为一个链式处理时,这里的catch实际作用对象是p.then返回的promise,而非p实例。实际是
var p = new Promise(function (resove, reject){
throw new Error('hehe');
})
p.then(function success(e){
console.log(e);
}, function fail(e){
console.log(e); // 实际这里会打印hehe
}).catch(function (e){
console.log(e); // 这里不执行
})
reject vs catch
引用标准文档https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
The catch() method returns a Promise and deals with rejected cases only. It behaves the same as calling Promise.prototype.then(undefined, onRejected).
其实reject跟catch是一个东西,无论throw 还是reject 都会执行onRejected调用。它们的区别在于throw不能用于异步调用中
如下代码所示,catch回调是不执行的
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
throw 'Uncaught Exception!';
}, 1000);
});
p1.catch(function(e) {
console.log(e); // This is never called
});
而reject回调是执行的
var p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('oh, no!');
}, 1000);
});
p2.catch(function(e) {
console.log(e); // "oh, no!"
})
深入理解 javascript异步异常处理
参考
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch