Async Generator配合for await...of是处理按需拉取、逐段消费异步数据流最自然的方式;用async function*定义,yield Promise或普通值,for await自动调用next()并等待Promise解析。

Async Generator(异步生成器)配合 for await...of 是处理**按需拉取、逐段消费的异步数据流**(比如分页接口、实时日志、流式响应)最自然的方式。它让异步迭代像同步循环一样简洁,同时保持非阻塞和内存友好。
异步生成器怎么写?
用 async function* 定义,内部 yield 的可以是 Promise 或普通值;每次 yield 后会暂停,等待消费者调用 next()(for await 会自动处理)。
例如:模拟分页获取用户列表:
async function* fetchUsersPaginated() {
let page = 1;
while (true) {
const res = await fetch(`/api/users?page=${page}`);
const users = await res.json();
if (users.length === 0) break;
for (const user of users) {
yield user; // 每次只 yield 一个用户,不一次性加载全部
}
page++;
}
}
用 for await...of 消费它
for await...of 专为异步可迭代对象(如 AsyncGenerator)设计。它自动调用 next(),等待每个 yield 返回的 Promise 解析后,再把解析值赋给变量。
立即学习“Java免费学习笔记(深入)”;
继续上面的例子:
(async () => {
for await (const user of fetchUsersPaginated()) {
console.log('处理用户:', user.name);
// 这里可以做异步操作,比如保存到本地、渲染到页面等
await saveToDB(user);
}
console.log('所有用户处理完成');
})();
注意边界与控制流
异步生成器不是无限运行的黑盒——你需要明确终止条件(如空数据、错误状态、手动 break),否则可能陷入死循环或内存泄漏。
- 在生成器内部用
break或return结束迭代 - 消费者中可用
break、continue或throw提前退出 - 若某次
yield抛错,会被for await捕获,可加try/catch - 不要在生成器里
await长时间无响应的请求,建议加超时或重试逻辑
常见组合场景
这类模式特别适合:
- 从 SSE(Server-Sent Events)或 WebSocket 流中逐条读取消息
- 处理大文件的分块读取(配合
ReadableStream+getReader()) - 轮询接口直到满足某个业务条件(如“等待订单状态变为 success”)
- 构建可复用的数据管道,比如
async function* filterAsync(gen, predicate)


















