下方这段代码的输出是什么?
重要程度: 5
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
Promise.resolve().then(() => setTimeout(() => console.log(4)));
Promise.resolve().then(() => console.log(5));
setTimeout(() => console.log(6));
console.log(7);
输出结果为:1 7 3 5 2 6 4。
这道题其实很简单,我们只需要知道微任务和宏任务队列是如何工作的。
让我们一起一步一步地看看发生了什么。
console.log(1);
// 第一行立即执行,它输出 `1`。
// 到目前为止,宏任务队列和微任务队列都是空的。
setTimeout(() => console.log(2));
// `setTimeout` 将回调添加到宏任务队列。
// - 宏任务队列中的内容:
// `console.log(2)`
Promise.resolve().then(() => console.log(3));
// 将回调添加到微任务队列。
// - 微任务队列中的内容:
// `console.log(3)`
Promise.resolve().then(() => setTimeout(() => console.log(4)));
// 带有 `setTimeout(...4)` 的回调被附加到微任务队列。
// - 微任务队列中的内容:
// `console.log(3); setTimeout(...4)`
Promise.resolve().then(() => console.log(5));
// 回调被添加到微任务队列
// - 微任务队列中的内容:
// `console.log(3); setTimeout(...4); console.log(5)`
setTimeout(() => console.log(6));
// `setTimeout` 将回调添加到宏任务队列
// - 宏任务队列中的内容:
// `console.log(2); console.log(6)`
console.log(7);
// 立即输出 7
总结一下:
- 立即输出数字
1
和7
,因为简单的console.log
调用没有使用任何队列。 - 然后,主代码流程执行完成后,开始执行微任务队列。
- 其中有命令行:
console.log(3); setTimeout(...4); console.log(5)
。 - 输出数字
3
和5
,setTimeout(() => console.log(4))
将console.log(4)
调用添加到了宏任务队列的尾部。 - 现在宏任务队列中有:
console.log(2); console.log(6); console.log(4)
。
- 其中有命令行:
- 当微任务队列为空后,开始执行宏任务队列。并输出
2
、6
和4
。
最终,我们的到的输出结果为:1 7 3 5 2 6 4
。