所属板块:4. 异步编程与事件循环
记录日期:2026-03-xx
更新:遇到 async/await 输出题或并发控制题时补充
1. Generator 函数(过渡期方案)
Generator 是 ES6 引入的“可暂停/恢复执行”的函数,用 function* 定义,yield 暂停。
function* gen() {
yield 1;
yield 2;
return 3;
}
const g = gen();
console.log(g.next()); // { value: 1, done: false }
console.log(g.next()); // { value: 2, done: false }
console.log(g.next()); // { value: 3, done: true }
它本身不能直接处理异步,但结合执行器(如 co 库)可以实现异步流程控制,为 async/await 铺路。
2. async/await 的本质(Generator + Promise 语法糖)
async/await 是 Generator + Promise 的语法糖:
async函数的返回值一定是一个 Promiseawait后面如果不是 Promise,会被自动Promise.resolve()包装await下方的代码会被包装成.then()回调,推入微任务队列(结合 [4-1] 事件循环)
async function test() {
console.log("1");
await Promise.resolve("await");
console.log("2");
}
test();
console.log("3");
输出:1 → 3 → 2(await 转为微任务)
3. await 在 Event Loop 中的真实表现(极其重要)
await右侧表达式同步执行await下方的所有代码被包装成微任务- 如果 await 的是已 resolved 的 Promise,仍会推入微任务队列(不会立即执行)
经典对比:
async function asyncFunc() {
console.log("async start");
await Promise.resolve();
console.log("async end");
}
asyncFunc();
console.log("global");
输出:async start → global → async end
4. 实战场景与错误处理
推荐写法(try...catch):
async function fetchData() {
try {
const res = await fetch('/api');
const data = await res.json();
return data;
} catch (err) {
console.error("请求失败", err);
}
}
并发优化误区(最容易踩坑):
// 错误写法:串行执行
for (const url of urls) {
const data = await fetch(url); // 一个接一个
}
// 正确写法:先并发启动,再 await
const promises = urls.map(url => fetch(url));
const results = await Promise.all(promises);
5. 小结 & 第四板块完结
- Generator 是“可暂停函数”,async/await 是其语法糖 + Promise 结合
- await 本质是微任务调度(必须结合 [4-1] 事件循环理解)
- [4-1] 事件循环 + [4-2] Promise + 本文 async/await,共同构成了 JS 异步编程的完整体系
第四板块(异步编程与事件循环)到此全部结束。
这是 JS 单线程下最核心的“动态调度机制”,掌握后刷输出题和写并发代码会非常顺手。
返回总目录:戳这里