单线程中同时读取多个异步迭代器的原生方案咨询
原生方案实现异步生成器值合并累加
你的需求可以通过**手动管理异步迭代器的next()方法 + Promise.all**实现,完全不需要自定义复杂迭代器,属于原生方案:
async function* base1(){ while(true) yield 1 } async function* base2(){ while(true) yield 2 } async function* accumulator() { // 获取两个异步生成器的迭代器实例 const iter1 = base1(); const iter2 = base2(); while (true) { // 并行等待两个迭代器产出下一个值 const [val1, val2] = await Promise.all([ iter1.next().then(res => res.value), iter2.next().then(res => res.value) ]); // 累加后输出 yield val1 + val2; } }
方案可行性说明
- 直接持有两个迭代器引用,避免了
for await顺序遍历导致的单迭代器阻塞问题 Promise.all并行等待两个next()结果,确保每次能同时拿到两个生成器的最新产出值- 所有
yield操作都在生成器主线程内执行,完全符合语法要求
你之前方案的问题分析
- 第一个方案用顺序
for await遍历,第一个无限循环的迭代器会永久阻塞主线程,导致第二个遍历逻辑永远无法执行 - 第二个方案在微任务中调用
yield,但yield只能在生成器函数的直接执行上下文里使用,异步回调/微任务中调用会直接抛出语法错误
适配终止场景的扩展
如果基础生成器可能终止(非无限循环),可以在next()后检查done状态来终止合并逻辑:
async function* accumulator() { const iter1 = base1(); const iter2 = base2(); while (true) { const [res1, res2] = await Promise.all([iter1.next(), iter2.next()]); // 任一迭代器完成则终止合并 if (res1.done || res2.done) break; yield res1.value + res2.value; } }
内容的提问来源于stack exchange,提问作者Товарищ Понечка
相关产品推荐
相关产品推荐

