如何实现按Promise完成顺序yield结果的异步生成器AwaitAsTheyCome
更简洁的实现方案
核心思路是利用Promise.race持续获取当前最先完成的Promise,逐步消费所有任务:
async function* AwaitAsTheyCome(promises) { const pending = new Set(); for (const originalPromise of promises) { // 包装原始Promise,完成后主动从待处理集合移除自身 const wrapped = originalPromise.then(result => { pending.delete(wrapped); return result; }); pending.add(wrapped); } while (pending.size) { yield await Promise.race(pending); } }
实现说明
- 对每个输入的Promise做轻量包装,通过闭包捕获包装后的Promise实例,保证任务完成后能主动从待处理集合中删除自己,避免重复消费
- 用
Set存储待处理的Promise,增删操作简洁高效 - 每次迭代都通过
Promise.race拿到当前最快完成的结果,直接yield给外层for await循环,输出时序和你原来的then绑定方案完全一致
你可以直接用你提供的sleep示例测试,输出结果和之前完全相同:
promise resolved: slept 1000 promise resolved: slept 2000 promise resolved: slept 3000 promise resolved: slept 4000 promise resolved: slept 5000
如果后续需要支持Promise拒绝的场景,只需要在包装层加对应的catch逻辑即可。
内容的提问来源于stack exchange,提问作者Don Hatch
相关产品推荐
相关产品推荐

