这道题是大厂面试常考题,核心考察对事件循环和微任务队列的理解。
✅ 第 14 题:Promise.then 链式调用执行顺序
📘 一、核心概念
- Promise.then / catch / finally 回调都是微任务(microtask)
- 微任务队列:当前宏任务执行完后立即执行所有微任务
- 同步代码先执行 → 微任务 → 宏任务
📘 二、经典题目
javascript
console.log('script start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve().then(() => {
console.log('promise1');
}).then(() => {
console.log('promise2');
});
console.log('script end');
📘 三、详细分析(步步解析)
- 同步执行
arduino
console.log('script start') // 输出 1
console.log('script end') // 输出 2
- 微任务队列(Promise.then)
- 第一个 then 回调 → 输出 'promise1'
- 第二个 then 回调 → 输出 'promise2'
- 宏任务队列(setTimeout)
- 输出 'setTimeout'
📘 四、最终输出顺序
arduino
script start
script end
promise1
promise2
setTimeout
✅ 面试官非常喜欢问这个输出顺序。
📘 五、速记卡(10 秒复盘版)
javascript
🎯 同步代码 > 微任务(Promise.then) > 宏任务(setTimeout/setInterval/IO)
🎯 Promise.then 内再 then → 链式微任务,依次执行
🎯 核心点:
- Promise.then 回调总是微任务
- 微任务会在当前宏任务结束后立即执行
- 微任务内部再生成微任务,会追加到队列末尾
📘 六、拓展题(加分)
javascript
Promise.resolve()
.then(() => {
console.log('1');
setTimeout(() => console.log('2'), 0);
})
.then(() => console.log('3'));
输出顺序:
1
3
2
解释:
- '1' → 微任务队列第一个
- setTimeout → 宏任务
- 第二个 then → 微任务队列末尾,紧跟 '1' 执行
- 宏任务最后执行 '2'