初遇困惑
但面对这道题时,就疑惑:"为什么4会在3之后打印? "
初次解题时的错误推导
// 错误预期:0 1 2 4 3 5 6
// 实际结果:0 1 2 3 4 5 6
一、面试真题再现
请写出以下代码的打印顺序:
Promise.resolve()
.then(() => {
console.log(0)
return Promise.resolve(4)
})
.then((res) => {
console.log(res)
})
Promise.resolve()
.then(() => {
console.log(1)
})
.then(() => {
console.log(2)
})
.then(() => {
console.log(3)
})
.then(() => {
console.log(5)
})
.then(() => {
console.log(6)
})
正确答案:0 1 2 3 4 5 6
二、深度执行过程解析
第〇阶段 - 初始化
初始微任务队列:[]
第一阶段 - 同步代码执行
- 创建两个已完成的Promise实例
- 注册各自的
.then回调
微任务队列:
[ 第一个Promise的then1, 第二个Promise的then1 ]
第二轮 - 首轮微任务执行
执行第一个Promise.then1
- 打印
0 - 返回
Promise.resolve(4)(产生新的Promise)
执行第二个Promise.then1
- 打印
1 - 返回普通值(自动包装为Promise)
微任务队列新增:
第一个链需要等待Promise.resolve(4)解析 → 产生两个隐式微任务
第二个链的then2入队
第三轮 - 次轮微任务执行
执行第二个Promise.then2
- 打印
2 - 返回普通值
微任务队列新增:
第二个链的then3入队
第一个链继续等待解析(此时尚未处理)
第四轮 - 关键转折点
执行第二个Promise.then3
- 打印
3 - 返回普通值
此时第一个链的Promise.resolve(4)解析完成,触发两个微任务:
1. 处理第一个链的then2回调
2. 继续后续链式调用
第五轮 - 异步结果处理
执行第一个Promise.then2
- 打印
4
执行第二个Promise.then4
- 打印
5
最终轮 - 收尾阶段
执行第二个Promise.then5
- 打印
6
三、核心机制图解
graph TD
A[同步代码] --> B[微任务队列初始化]
B --> C[执行第一个then1]
C --> D[触发Promise解析]
B --> E[执行第二个then1]
E --> F[链式入队then2]
F --> G[执行then2]
G --> H[链式入队then3]
H --> I[执行then3]
I --> J[解析完成触发回调]
J --> K[执行第一个then2]
K --> L[执行后续then4]
L --> M[执行最后then5]
四、关键知识点总结
-
双阶段Promise解析
当.then()返回Promise时,会产生两个隐式微任务:- 等待Promise状态变更
- 执行后续回调
-
链式调用优先级
每个.then()都会创建新的微任务,即使返回普通值 -
事件循环特性
同一层级的微任务按入队顺序执行,但嵌套Promise会打破线性顺序 -
V8引擎优化
现代浏览器对Promise.resolve的快速路径优化会影响执行细节
五、题目来源声明
本题目源自知名技术面试平台 面试派(mianshipai.com) ,该平台汇集了各大厂最新面试真题,特别感谢其精心整理的优质题库为开发者提供的学习支持。建议读者访问官网获取更多面试资源。