JavaScript迭代器和生成器本身是同步协议,但async function*可创建AsyncIterator,配合for await...of实现异步遍历;需注意yield非return、done:true为终止信号、不可混用async与普通for...of。
JavaScript 的迭代器和生成器本身不简化异步——它们是同步协议,但能被 async 修饰后成为 AsyncIterator,再配合 for await...of 实现“看起来像同步”的异步遍历。直接拿 function* 去处理 Promise 链,不加 async 会出错。
next() 方法一个迭代器是一个有 next() 方法的对象,该方法返回形如 { value, done } 的对象。它不关心数据怎么来,只承诺每次调用都推进并返回下一个状态。
常见错误:手动实现迭代器时忘记在末尾返回 { value: undefined, done: true },导致循环卡死或无限重复最后一项。
done: true 是终止信号,不是可选提示[Symbol.iterator]() 返回的就是标准迭代器for...of,必须在 [Symbol.iterator] 方法里返回迭代器对象function* 生成器函数返回迭代器,不是执行函数体调用 functi 只创建并返回一个迭代器对象,函数体代码不会立即运行。只有第一次调用
on* () {}next() 才开始执行,遇到 yield 暂停,并把 yield 后的值作为 value 返回。
容易踩的坑:
yield 不是 return,函数没结束,上下文(变量、执行位置)被保留next() 会从上次暂停处继续,直到函数退出或遇到 return
new 调用,会报 TypeError: Generator is not a constructor
function* countdown(n) {
while (n > 0) yield n--;
}
const iter = countdown(3);
iter.next(); // { value: 3, done: false }
iter.next(); // { value: 2, done: false }
iter.next(); // { value: 1, done: false }
iter.next(); // { value: undefined, done: true }
async function* 创建异步迭代器,需用 for await...of
普通生成器无法 await,但加上 async 关键字后,yield 可以产出 Promise,且整个函数返回的是 AsyncIterator,其 next() 方法返回 Promise。
关键约束:
async function* 和普通 for...of,会得到 pending Promise 而非解包后的值for await...of 内部自动 await 每次 next().value,但要求可迭代对象满足 [Symbol.asyncIterator] 接口AsyncIterator,浏览器中需 Chrome 63+ / Firefox 57+async function* fetchLines(url) {
const response = await fetch(url);
const reader = response.body.getReader();
let { value, done } = await reader.read();
while (!done) {
yield new TextDecoder().decode(value);
({ value, done } = await reader.read());
}
}
// 正确用法:
for await (const line of fetchLines('/log.txt')) {
console.log(line);
}
真正让异步“变简单”的不是生成器本身,而是语言层面对 AsyncIterator 协议的支持——它把流式异步数据(比如 HTTP 流、EventSource、数据库游标)统一成可遍历结构。漏掉 async 或误用 for...of 就会掉进 Promise 套娃陷阱。