下方这段代码的输出是什么?
重要程度: 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。