🔥 深入解析Promise并发控制:all
、any
、race
三大方法实战手册
Promise的核心作用
JavaScript作为单线程语言,为避免同步代码阻塞影响用户体验,采用异步机制处理非即时任务。主线程执行同步代码时,异步任务(如Promise
)会被推入消息队列 。其中,Promise.then()
产生的微任务(Microtask) 具有最高优先级,优先于宏任务(如setTimeout
)执行,从而高效管理异步流程。
**Promise.all()
:全成功才成功**
特点:
- 接收Promise数组,返回新Promise
- 全成功:返回结果数组(按输入顺序)
- 一票否决:任一失败则立即拒绝,返回首个错误
适用场景 :
多个强依赖的并行任务需全部成功(如同时请求多个API)。
代码实现:
js
Promise.myAll = function(promises) {
let results = []; // 存储结果(保证顺序)
let completed = 0; // 完成计数器
return new Promise((resolve, reject) => {
promises.forEach((promise, index) => {
Promise.resolve(promise) // 处理非Promise值
.then(value => {
results[index] = value; // 按索引存入结果
completed++;
if (completed === promises.length) {
resolve(results); // 全部成功时返回结果数组
}
})
.catch(reject); // 任一失败立即拒绝
});
});
};
**Promise.any()
:一成功就成功**
特点:
- 接收Promise数组,返回新Promise
- 一票通过:任一成功则立即返回该结果
- 全败才拒 :全部失败时拒绝,返回
AggregateError
(含所有错误)
适用场景 :
容错场景(如从多个备用源获取最快可用数据)。
代码实现:
javascript
javascript
javascript
复制
Promise.myAny = function(promises) {
let errors = []; // 存储所有错误
let failed = 0; // 失败计数器
return new Promise((resolve, reject) => {
promises.forEach((promise, index) => {
Promise.resolve(promise)
.then(resolve) // 任一成功立即解决
.catch(err => {
errors[index] = err; // 按索引记录错误
failed++;
if (failed === promises.length) {
// 全部失败时返回聚合错误
reject(new AggregateError(errors, "All promises were rejected"));
}
});
});
});
};
**Promise.race()
:先到先得**
特点:
- 接收Promise数组,返回新Promise
- 速度竞赛:采用首个敲定状态(无论成功/失败)的结果
适用场景 :
超时控制(如网络请求限时响应)。
代码实现:
javascript
Promise.myRace = function(promises) {
return new Promise((resolve, reject) => {
for (const promise of promises) { // 遍历可迭代对象
Promise.resolve(promise) // 处理非Promise值
.then(resolve) // 首个成功则解决
.catch(reject); // 首个失败则拒绝
}
});
};
三大方法对比总结
方法 | 解决条件 | 拒绝条件 | 适用场景 |
---|---|---|---|
Promise.all |
所有Promise成功 | 任一Promise失败 | 强依赖的并行任务(如多API) |
Promise.any |
任一Promise成功 | 所有Promise失败 | 容错处理(如多数据源择优) |
Promise.race |
首个Promise状态敲定 | 首个Promise状态敲定 | 竞速场景(如超时控制) |
关键提示:
Promise.all
的"快速失败"特性可能导致部分异步操作未终止Promise.any
的聚合错误(AggregateError
)需特殊处理- 空数组输入:
all
立即解决,race
永久挂起,any
拒绝