关于Promise.reject()回调在微任务队列中执行顺序的疑问
Promise catch回调在所有then回调后执行的原因
问题重现
测试代码:
Promise.resolve().then(()=>console.log("Resolved1 Promise")); Promise.reject().then(()=>console.log("Resolved2 Promise")).catch(()=>console.log('Rejected2 Promise')); Promise.resolve().then(()=>console.log("Resolved3 Promise")); Promise.resolve().then(()=>console.log("Resolved4 Promise")); Promise.resolve().then(()=>console.log("Resolved5 Promise"));
预期输出:
Resolved1 Promise Rejected2 Promise Resolved3 Promise Resolved4 Promise Resolved5 Promise
实际输出:
Resolved1 Promise Resolved3 Promise Resolved4 Promise Resolved5 Promise Rejected2 Promise
原因解释
核心原因在于Promise链式调用中,then方法返回的新Promise的状态变更,是通过微任务异步完成的,而非同步确定。具体流程拆解:
同步代码执行阶段
- 第一个
Promise.resolve().then():原Promise已处于fulfilled状态,直接将对应回调加入微任务队列。 Promise.reject().then(...):原Promise处于rejected状态,但传入then的是仅处理fulfilled状态的回调,因此会安排一个微任务——该微任务不会执行传入的回调,而是将then返回的新Promise标记为rejected。此时这个新Promise的状态还是pending,后续的catch回调仅被注册,不会立即加入微任务队列。- 后面三个
Promise.resolve().then():依次将对应回调加入微任务队列,此时微任务队列顺序为:[Resolved1回调, then状态变更微任务, Resolved3回调, Resolved4回调, Resolved5回调]
- 第一个
微任务处理阶段
- 先执行
Resolved1回调,输出Resolved1 Promise。 - 执行
then状态变更微任务:将then返回的新Promise标记为rejected,此时才会触发后续注册的catch回调,将其加入微任务队列末尾。 - 接着依次执行
Resolved3、Resolved4、Resolved5的回调,输出对应内容。 - 最后执行刚加入的
catch回调,输出Rejected2 Promise。
- 先执行
简单来说,catch回调的微任务是在then返回的Promise状态变更的微任务执行后才被添加的,自然排在了所有预先加入的then回调之后。
内容的提问来源于stack exchange,提问作者Muhammad Hamza Maqsood
相关产品推荐
相关产品推荐

