javascript中promise本身不支持并发限制,需通过队列、计数器和调度逻辑实现;常用方案包括promisepool封装固定并发池、分片+promise.all简单节流、以及支持运行时setlimit的可调限流类。

JavaScript 中 Promise 本身不提供原生的并发数量限制能力,但可以通过组合队列、计数器和调度逻辑,实现高效、可动态调整的并发控制。核心不是“阻止 Promise 创建”,而是“控制 Promise 的执行时机”。
用 PromisePool 封装固定并发池
这是最常用也最直观的方式:预设最大并发数,按需填充执行槽位,任务完成自动补位。
- 维护一个 running 计数器,记录当前正在 pending 的请求数
- 准备一个待执行任务队列(如数组),每个任务是返回 Promise 的函数(() => fetch(url))
- 启动时循环调用:只要 running 且队列非空,就取出一个任务执行,并对它的 Promise 添加 .finally(() => { running--; scheduleNext(); })
- 无需等待整批完成,新任务可随时加入队列,系统自动平滑调度
用分片 + Promise.all 实现简单节流
适合一次性批量请求、并发上限固定、不需运行时调整的场景,代码简洁易懂。
- 将全部 URL 列表按 maxConcurrent 分成多个子数组(如每组 5 个)
- 用 for...of 依次遍历每组,对每组调用 Promise.all(group.map(fetch))
- 前一组全部完成后再发下一组,天然串行化批次,但组内完全并行
- 优点是零依赖、无状态管理;缺点是无法动态扩缩容,且存在“组间空档期”资源浪费
封装可调限流类支持运行时 setLimit
当业务需要根据网络状况或用户操作实时调整并发量(比如弱网降为 2,Wi-Fi 升至 6),推荐面向对象封装。
- 类内部持有 maxConcurrency(可修改)、activeCount(实时计数)、queue(FIFO 待执行函数数组)
- 暴露 add(promiseFn) 方法添加任务,setLimit(n) 修改上限(只影响后续调度)
- 关键方法 drain():只要 activeCount ,就 pop 一个任务执行并递增 activeCount
- 每个任务 Promise 必须链上 .finally(done),其中 done 负责 activeCount-- 并再次调用 drain(),确保失败请求不卡死槽位
选对方法比手写更重要
不要一上来就造轮子。先确认需求:
- 只需等全部结果 → 用 Promise.all(任一失败即终止)
- 要收集所有结果,不管成败 → 用 Promise.allSettled
- 只关心最快响应 → 用 Promise.race
- 要控数量、保稳定、可伸缩 → 上 PromisePool 或可调限流类
不复杂但容易忽略:失败处理必须进 finally,否则并发槽位会泄露。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











