关于Promise执行顺序的疑问:为何输出‘1 2 11 22’而非‘1 2 22 11’?
为什么Promise链式调用的输出顺序是1 2 11 22而不是1 2 22 11?
嘿,这个问题其实是理解Promise微任务执行顺序的经典场景,我来一步步拆解给你看:
首先先贴下你的代码:
new Promise((res, rej) => { res(); }) .then(() => { console.log(1); new Promise((res, rej) => { res(); }) .then(() => { console.log(2); }) .then(() => { console.log(22); }); }) .then(() => { console.log(11); });
要搞懂这个问题,核心是记住两个关键点:
- JavaScript事件循环里的微任务队列是按顺序逐个处理的,只有当前微任务执行完,才会去取下一个;
- Promise的
then回调,必须等当前Promise的状态变为resolved后才会进入微任务队列,而且链式调用里的下一个then,必须等前一个then的回调执行完毕,才会被加入队列。
接下来我们一步步走执行流程:
1. 同步代码阶段
- 创建第一个Promise,执行
res(),这个Promise立刻变成resolved状态; - 调用它的第一个
.then(),这个打印1的回调被加入微任务队列; - 同步代码执行完毕,开始处理微任务队列。
2. 处理第一个微任务(打印1的回调)
- 先执行
console.log(1),输出1; - 创建第二个Promise,执行
res(),它也立刻变成resolved状态; - 调用第二个Promise的第一个
.then(),这个打印2的回调被加入微任务队列; - 此时第二个Promise的第二个
.then()(打印22)还进不了队列——因为它得等前一个then(打印2)执行完,这个Promise的状态才会因为前一个then的返回值变成resolved,才能触发下一个then的回调入队; - 第一个Promise的第一个then回调执行完了,它没有return值,JavaScript会自动把它包装成一个resolved状态的Promise,所以第一个Promise的第二个
.then()(打印11)的回调被加入微任务队列。
现在微任务队列的顺序是:[打印2的回调, 打印11的回调]
3. 处理下一个微任务(打印2的回调)
- 执行
console.log(2),输出2; - 这个回调执行完后,第二个Promise的前一个then返回了undefined,被包装成resolved的Promise,所以第二个Promise的第二个
.then()(打印22)的回调被加入微任务队列。
现在微任务队列的顺序是:[打印11的回调, 打印22的回调]
4. 处理下一个微任务(打印11的回调)
- 执行
console.log(11),输出11。
5. 处理最后一个微任务(打印22的回调)
- 执行
console.log(22),输出22。
这样走下来,最终的输出顺序就是1 2 11 22啦。
内容的提问来源于stack exchange,提问作者Aibin
相关产品推荐
相关产品推荐

