回到课程

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

重要程度: 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