多个Promise.then调用场景下是否真的存在调度竞争问题?
结论:这段代码在所有符合ECMAScript和HTML标准的实现中不存在任何调度竞争,输出顺序是完全固定的
原回答提到的「调度竞争」是错误的,所有Promise回调的执行顺序被标准严格约束,不存在引擎自行决定执行顺序的空间:
核心依据
- 浏览器环境下,HTML标准明确规定每个事件循环只有一个微任务队列,所有微任务按**先进先出(FIFO)**顺序执行,同类型微任务没有优先级差异
- ES6标准明确规定所有Promise的then回调产生的作业都会进入单一的
PromiseJobs队列,同样按FIFO顺序执行,不存在多个同类型队列的调度选择问题
固定执行与输出顺序
所有符合标准的环境运行这段代码的输出顺序完全一致,过程如下:
- 同步代码执行阶段
- 首先执行第23行同步代码,输出
1 - setTimeout回调作为宏任务进入宏任务队列,优先级低于所有微任务,最后执行
- 首先执行第23行同步代码,输出
- 微任务队列清空阶段(严格按入队顺序执行)
- 执行第一层第一个then回调:输出
2 A,返回值B触发下一层then入队 - 执行第一层第二个then回调:
- 第5行
Promise.resolve('C').then()的回调进入微任务队列 - 执行第10行输出
3 B,返回值B触发下一层then入队
- 第5行
- 执行C的第一个then回调:输出
7 C,无返回值触发C的第二个then入队 - 执行第一层第三个then回调:
- 第13行
Promise.resolve('D').then()的回调进入微任务队列 - 执行第18行输出
4 B,无返回值触发下一层then入队
- 第13行
- 执行C的第二个then回调:输出
8 undefined - 执行D的第一个then回调:输出
9 D,无返回值触发D的第二个then入队 - 执行第一层第四个then回调:输出
5 undefined - 执行D的第二个then回调:输出
10 undefined
- 执行第一层第一个then回调:输出
- 宏任务执行阶段
- 执行setTimeout回调,输出
6
- 执行setTimeout回调,输出
关于原回答错误的说明
原回答之所以提到「调度竞争」,本质是对标准中微任务/Promise作业队列的规则理解有误。只有当涉及未被标准明确定义优先级的跨类型异步任务(比如部分宿主环境自定义的微任务、不同类型宏任务的执行顺序)时,才可能出现实现差异。这段代码中所有异步回调都属于标准明确规定顺序的Promise微任务,不存在任何调度自由度。
内容的提问来源于stack exchange,提问作者Brady Chen
相关产品推荐
相关产品推荐

