You need to enable JavaScript to run this app. JS Promise链式调用.then.catch执行顺序差异问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

JS Promise链式调用.then.catch执行顺序差异问题咨询

Promise 链式调用运行逻辑解答

核心前置规则

  • 所有同步代码优先执行完毕,才会按先进先出的顺序执行微任务队列的任务
  • then/catch每次调用都会返回全新的Promise实例,后续链式方法都是绑定到这个新实例上,而非最初的Promise
  • 只有当某个Promise实例状态确定为fulfilled/rejected时,才会将它绑定的对应回调加入微任务队列,状态传递本身也会占用微任务位置

第一种情况:注释then(x => console.log(5)),输出1 6 3 7的原因

同步执行阶段

两个Promise链同步初始化完成后,微任务队列初始有2个任务:

  1. 第一个链的then(x => console.log(1))回调(因为Promise.resolve(1)已经是fulfilled状态)
  2. 第二个链第一个then(x => console.log(4))的状态传递任务(因为Promise.reject(1)是rejected状态,这个then没有onRejected回调,返回的新Promise要继承rejected状态,这个处理需要占一个微任务位)

微任务执行流程

  1. 执行第一个任务:打印1,这个then返回的Promise变为fulfilled,触发后续catch的状态传递任务加入微任务队列
  2. 执行第二个任务:第二个链第一个then返回的Promise变为rejected,触发后续catch(x => console.log(6))回调加入微任务队列
  3. 现在队列里的任务顺序是「第一个链catch的状态传递任务」、「log6回调」
  4. 执行catch的状态传递任务:因为前序是fulfilled状态,catch不触发,直接触发后续then(x => console.log(3))回调加入队列
  5. 执行log6回调:打印6,这个catch返回的Promise变为fulfilled,触发后续then(x => console.log(7))回调加入队列
  6. 现在队列里的任务顺序是「log3回调」、「log7回调」,依次执行打印3、7
    最终输出顺序就是1 6 3 7

第二种情况:取消注释then(x => console.log(5)),输出1 3 6 7的原因

多出来的这个then会在第二个链上多一层Promise实例,多一次状态传递的微任务:

同步执行阶段

初始微任务队列还是2个任务:log1回调、第二个链第一个then的状态传递任务

微任务执行流程

  1. 执行第一个任务:打印1,触发第一个链catch的状态传递任务加入队列
  2. 执行第二个任务:第二个链第一个then返回rejected,触发第二个链第二个then(x => console.log(5))的状态传递任务加入队列
  3. 现在队列里的任务顺序是「第一个链catch的状态传递任务」、「第二个链第二个then的状态传递任务」
  4. 执行第一个链catch的状态传递任务:触发log3回调加入队列
  5. 执行第二个链第二个then的状态传递任务:这个then也没有onRejected回调,返回的Promise继承rejected,触发catch(x => console.log(6))回调加入队列
  6. 现在队列里的任务顺序是「log3回调」、「log6回调」,依次执行打印3、6
  7. log6执行完后触发log7回调加入队列,执行后打印7
    最终输出顺序就是1 3 6 7

内容的提问来源于stack exchange,提问作者snowy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 20:57:01