You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于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的状态变更,是通过微任务异步完成的,而非同步确定。具体流程拆解:

  1. 同步代码执行阶段

    • 第一个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回调]
  2. 微任务处理阶段

    • 先执行Resolved1回调,输出Resolved1 Promise。
    • 执行then状态变更微任务:将then返回的新Promise标记为rejected,此时才会触发后续注册的catch回调,将其加入微任务队列末尾。
    • 接着依次执行Resolved3、Resolved4、Resolved5的回调,输出对应内容。
    • 最后执行刚加入的catch回调,输出Rejected2 Promise。

简单来说,catch回调的微任务是在then返回的Promise状态变更的微任务执行后才被添加的,自然排在了所有预先加入的then回调之后。

内容的提问来源于stack exchange,提问作者Muhammad Hamza Maqsood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:22:04