Promise 并发控制方法详解
一、核心静态方法概念
| 方法 | 描述 | 特性 | 结果 |
|---|---|---|---|
Promise.all(iterable) |
等待所有 Promise 成功 | 短路特性(一个失败立即拒绝) | 成功:结果数组 失败:第一个错误 |
Promise.race(iterable) |
采用第一个完成的 Promise | 竞速机制 | 第一个落定的结果(无论成功/失败) |
Promise.allSettled(iterable) |
等待所有 Promise 完成 | 不短路,收集所有结果 | 状态描述对象数组 |
二、手写实现
1. 手写 Promise.all
1 | Promise.myAll = function(promises) { |
2. 手写 Promise.race
1 | Promise.myRace = function(promises) { |
3. 手写 Promise.allSettled
1 | Promise.myAllSettled = function(promises) { |
三、使用 Promise 实现请求并发控制
1 | class RequestPool { |
使用示例:
1 | // 1. 创建并发池(最大3个) |
四、关键实现原理
并发控制核心逻辑:
- 任务队列:存储等待执行的任务
- 运行计数器:跟踪当前执行中的任务数
- 自动补位机制:任务完成时自动触发下一个任务
Promise 方法实现要点:
- 正确处理非 Promise 值(
Promise.resolve()包装) - 保持结果顺序(数组索引定位)
- 短路处理(
all的立即拒绝)
- 正确处理非 Promise 值(
五、实际应用场景
| 场景 | 推荐方法 | 说明 |
|---|---|---|
| 批量表单提交 | Promise.all |
需要全部成功,任一失败终止 |
| 竞速请求 | Promise.race |
获取最快响应(如CDN检测) |
| 批量数据采集 | Promise.allSettled |
需要完整结果(无论成败) |
| 图片懒加载 | 并发控制 | 避免同时加载过多图片 |
| API 分页请求 | 并发控制 | 控制分页请求并发数量 |
六、特殊处理技巧
- 错误重试机制:
1 | pool.add(() => fetch(url).catch(() => fetch(url))) // 失败自动重试 |
- 优先级队列:
1 | // 高优先级任务 |
- 超时控制:
1 | pool.add(() => |
性能提示:浏览器通常有 6-8 个 TCP 连接限制,合理设置并发数可优化性能