JS async/await中await未暂停执行原因及Promise并发限制实现问题
问题根因
你之前遇到的await没有暂停、并发限制失效的问题,本质上是踩了Promise的基础特性的坑:Promise实例在创建的瞬间就会开始执行内部逻辑,没有任何办法暂停已经创建的Promise。
如果你最初调用runPromises的时候传入的是提前创建好的Promise数组,而非现在代码里用的「返回Promise的函数数组」,那么所有异步任务在你把它们塞进数组的时候就已经全部启动了,自然不会有并发限制效果,也会出现await没拦住代码执行的错觉。你现在改成传入Promise工厂函数,调用prom()的时候才创建实例启动任务,逻辑就完全通顺了。
现有代码优化
你当前的实现已经可以正常工作,还可以做一点简化,不需要额外维护counter变量,直接用队列queue的长度判断即可,优化后代码如下:
async function runPromises(promiseFactories, limit = 10) { const pending = [] const tasks = [...promiseFactories] while (tasks.length) { // 队列没满就塞新任务 if (pending.length < limit) { const task = tasks.shift() const p = task() pending.push(p) // 任务完成后自动从队列移除 p.then(() => pending.splice(pending.indexOf(p), 1)) } else { // 队列满了就等任意一个任务完成 await Promise.race(pending) } } // 等待剩下的所有任务执行完 await Promise.all(pending) }
效果验证
用你给出的测试用例,16个6秒的异步函数,限制并发10,最终输出的时间会在12000ms左右,符合预期:前10个任务执行6秒完成,后6个任务再执行6秒完成,总耗时就是两轮的时间。
内容的提问来源于stack exchange,提问作者SrdjaNo1
相关产品推荐
相关产品推荐

