<p>关键在于用 async function* 让 yield 天然产出 Promise,由异步生成器自动驱动链条;其返回 AsyncIterator,支持 for await...of 自动处理 next()、await 和错误,无需手动维护状态。</p>

关键不在“融合”,而在让 yield 天然产出 Promise,再由异步生成器自动驱动链条——这样就不需要手动调用 next(),也不用自己维护迭代器状态。
用 async function* 替代普通 generator
普通 function* 的 yield 返回的是同步值,而 async function* 的 yield 可以直接返回 Promise,且整个生成器本身返回一个异步迭代器。引擎会自动等待每个 yield 后的 Promise 解析完成,再继续执行下一段逻辑。
- 声明时加
async:函数体支持await,yield值会被自动包裹进 Promise - 调用后得到的是
AsyncIterator,不是普通Iterator -
for await...of会隐式调用next()并await每次返回的 Promise
让每个 yield 成为链条中的一环
yield 不是“暂停点”,而是“异步产出点”。只要 yield 出去的是 Promise(或可 thenable 对象),它就自然融入 Promise 链条——因为异步迭代器的 next() 方法规定必须返回 Promise,且该 Promise resolve 的结果必须是 { value, done }。
- 若
yield fetch('/api/user'),生成器会等请求完成,再把响应对象作为value向外传递 - 若
yield Promise.resolve(42),立刻产出42,不阻塞后续 - 错误会自动 throw 到生成器内部,可用
try/catch捕获,或由消费者通过for await...of的catch处理
避免手动 next() 的核心写法
真正消除臃肿,靠的是消费端统一用 for await...of,而不是自己写循环 + iterator.next()。
- 错误示范:
const it = myAsyncGen(); it.next().then(...).then(it.next())...—— 状态、错误、done 判断全得手写 - 正确写法:
for await (const item of myAsyncGen()) { console.log(item); }—— done 自动终止,reject 自动抛出,value 自动解包 - 配合
Promise.all或Promise.race时,可先转成数组:const items = await Array.fromAsync(myAsyncGen())(ES2024+)
链式组合时保持语义清晰
如果想把多个异步步骤串成一个可复用的流程,不要拼接 Promise 链,而是封装成独立的 async function*,再用 yield* 委托:
-
yield* fetchPages()→ 自动展开整个分页流,每一项都是解析后的数据 -
yield process(item)→ 同步处理;yield await delay(1000)→ 异步等待 - 整个流程对外仍是一个异步迭代器,消费者无需知道内部是 Promise 还是 await,只关心“按需拉取”

















