异步任务执行顺序
console.log(1);
async function foo() {
console.log(2);
await bar(); // 关键点:await 会暂停 foo 的执行
console.log(3); // 被放入微任务队列(在 bar 的 Promise 解决后)
}
async function bar() {
console.log(4);
await Promise.resolve(); // 暂停 bar 的执行
console.log(5); // 被放入微任务队列
}
setTimeout(() => console.log(6), 0); // 宏任务
foo();
new Promise(resolve => {
console.log(7);
resolve();
}).then(() => console.log(8)); // 微任务
console.log(9);
执行步骤详解:
-
同步代码执行:
console.log(1)→ 输出1- 调用
foo():console.log(2)→ 输出2- 调用
bar():console.log(4)→ 输出4await Promise.resolve()暂停bar,将console.log(5)放入微任务队列
await bar()暂停foo,将console.log(3)标记为等待(但尚未入队)
new Promise同步执行:console.log(7)→ 输出7resolve()→ 将console.log(8)放入微任务队列
console.log(9)→ 输出9- 当前输出:
1, 2, 4, 7, 9
-
微任务队列处理:
- 微任务队列初始内容:
[输出5, 输出8] - 执行第一个微任务:
console.log(5)→ 输出5- 关键:此时
bar()的 Promise 解决,触发foo()的等待结束 foo()中的console.log(3)被放入微任务队列
- 关键:此时
- 执行第二个微任务:
console.log(8)→ 输出8 - 执行第三个微任务:
console.log(3)→ 输出3 - 输出:
5, 8, 3
- 微任务队列初始内容:
-
宏任务队列处理:
- 执行
setTimeout回调:console.log(6)→ 输出6
- 执行
最终输出顺序:
1 → 2 → 4 → 7 → 9 → 5 → 8 → 3 → 6
关键机制说明:
-
await的双重暂停:await bar()暂停foo时,console.log(3)不会立即入队- 必须等待
bar()的 Promise 解决(即console.log(5)执行后),console.log(3)才加入微任务队列
-
微任务执行顺序:
-
优先级规则:
- 同步代码 > 已存在的微任务 > 新生成的微任务 > 宏任务
- 微任务队列按 先进先出 (FIFO) 顺序执行
常见误区:
- 误认为
await后的代码会立即入队(实际需等待右侧 Promise 解决) - 忽略链式微任务的动态生成(如
console.log(3)在console.log(5)执行后才入队) - 混淆微任务和宏任务的优先级(微任务总是优先于宏任务)
你的理解完全正确!这个顺序展示了 JavaScript 事件循环的精细调度机制。

787

被折叠的 条评论
为什么被折叠?



