Promise链式调用仅用末尾catch()的原因及底层执行逻辑问询
Promise链式调用的错误传递机制解析
提问
我理解promise3因解析为已拒绝的promise2而被拒绝,但promise3是如何拒绝promise4的?其底层执行机制是什么?同时,为何在Promise链式调用的末尾仅使用一个catch()就能捕获所有错误?
相关代码
Promise.resolve(6) // promise 1 .then(function(data) { console.log('then 1:' + data); return Promise.reject(new Error('ups - rejected')); // 它会直接跳到第一个catch吗? }) // promise 2 - 这个promise被解析为一个**已拒绝的promise** .then(function (data) { console.log('then 2:' + data); return data + 1; }) // promise 3 .then(function (data) { console.log('then 3:' + data); return data + 1; }) // promise 4 .catch(function(error) { // 是promise4的catch吗? console.log(error); });
执行输出
then 1:6 index.js:57 Error: ups - rejected at index.js:46:27
解答
一、Promise3如何拒绝Promise4?底层执行机制
Promise链式调用的核心规则是:每个then()或catch()都会返回一个全新的Promise实例,新Promise的状态完全由上一个环节的结果决定:
- 当promise2变成已拒绝状态后,调用它的
then()(也就是生成promise3的那个then())时,因为promise2是拒绝态,这个then()的成功回调会直接被跳过,promise3会自动继承promise2的拒绝状态和错误原因,不需要执行任何回调代码。 - 接着处理promise3的
then()(生成promise4的then())时,同样因为promise3是拒绝态,它的成功回调也被跳过,promise4直接继承promise3的拒绝状态和错误原因。
底层本质是Promise规范内置的错误冒泡机制:只要链式调用中某一个Promise进入拒绝态,后续所有then()的成功回调都会被忽略,每个后续Promise都会直接转为拒绝态,错误沿着链式方向自动向后传递,直到遇到能处理错误的回调。
二、为什么末尾一个catch()能捕获所有错误?
catch()本质是then(null, 错误回调)的语法糖,专门用来处理Promise的拒绝态:
- 链式调用中任何未被处理的拒绝态,都会一直向后传递,直到遇到第一个
catch()(或者带错误回调的then())。 - 只要在链式末尾放置一个
catch(),前面所有环节产生的、未被中间回调处理的错误,最终都会传递到这个catch()中被捕获处理。 - 就像你代码里的情况,promise2、3、4都是拒绝态,前面的
then()都没有错误回调,所以错误一直冒泡到末尾的catch()才被触发。
内容的提问来源于stack exchange,提问作者user19551894
相关产品推荐
相关产品推荐

