回到课程

下方这段代码的输出是什么?

重要程度: 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. 立即输出数字 17,因为简单的 console.log 调用没有使用任何队列。
  2. 然后,主代码流程执行完成后,开始执行微任务队列。
    • 其中有命令行:console.log(3); setTimeout(...4); console.log(5)
    • 输出数字 35setTimeout(() => console.log(4))console.log(4) 调用添加到了宏任务队列的尾部。
    • 现在宏任务队列中有:console.log(2); console.log(6); console.log(4)
  3. 当微任务队列为空后,开始执行宏任务队列。并输出 264

最终,我们的到的输出结果为:1 7 3 5 2 6 4