Promise的四个静态方法(all/allSettled/)
七崽爱吃小饼干2026/01/29阅读 3专栏 JavaScript
Promise 的 all、allSettled、race、any 这四个静态方法都用于处理多个 Promise 组成的数组(可迭代对象),返回值都是一个全新的 Promise,但它们的「触发成功/失败的条件」和「返回结果格式」有本质区别。
1. Promise.all():「全部成功才成功,一个失败就失败」
功能说明
- 接收一个 Promise 可迭代对象(通常是数组)。
- 只有所有 Promise 都变为
fulfilled(成功),返回的新 Promise 才会成功。 - 只要有一个 Promise 变为
rejected(失败),就会立即触发返回 Promise 的失败,且不会等待其他 Promise 执行完成(「快速失败」特性)。 - 成功返回的结果是一个数组,数组中结果的顺序和传入 Promise 数组的顺序完全一致(和执行完成顺序无关)。
代码示例
javascript
// 定义三个模拟 Promise
const p1 = Promise.resolve("结果1");
const p2 = new Promise((resolve) => setTimeout(() => resolve("结果2"), 1000));
const p3 = Promise.resolve("结果3");
// 正常情况:所有 Promise 都成功
Promise.all([p1, p2, p3])
.then((result) => {
console.log("all 成功结果:", result); // 输出:all 成功结果: ['结果1', '结果2', '结果3']
})
.catch((error) => {
console.log("all 失败结果:", error);
});
// 异常情况:有一个 Promise 失败
const p4 = Promise.reject("出错了!");
Promise.all([p1, p4, p2])
.then((result) => {
console.log("all 成功结果:", result);
})
.catch((error) => {
console.log("all 失败结果:", error); // 立即输出:all 失败结果: 出错了!(不会等待 p2 执行)
});
适用场景
需要等待多个异步操作全部完成后,再执行后续逻辑,且其中任何一个操作失败都无法继续的场景。 例如:提交表单前,需要同时获取用户信息、验证手机号、检查权限,三个接口都成功才能提交。
2. Promise.allSettled():「无论成败,全部等待完成」
功能说明
- 接收一个 Promise 可迭代对象。
- 无论传入的 Promise 是成功还是失败,都会等待所有 Promise 执行完成(无「快速失败」特性)。
- 返回的新 Promise 永远是成功状态,成功结果是一个对象数组,每个对象对应一个传入的 Promise,包含两个属性:
status:Promise 状态(fulfilled成功 /rejected失败)。value:status 为fulfilled时,对应的 Promise 成功结果(可选)。reason:status 为rejected时,对应的 Promise 失败原因(可选)。
代码示例
javascript
const p1 = Promise.resolve("结果1");
const p2 = new Promise((resolve) => setTimeout(() => resolve("结果2"), 1000));
const p3 = Promise.reject("出错了!");
Promise.allSettled([p1, p2, p3])
.then((result) => {
console.log("allSettled 结果:", result);
// 输出结果(数组顺序和传入顺序一致):
// [
// { status: 'fulfilled', value: '结果1' },
// { status: 'fulfilled', value: '结果2' },
// { status: 'rejected', reason: '出错了!' }
// ]
});
适用场景
需要获取所有异步操作的完整结果(成功/失败都要),不希望某个操作失败中断其他操作的场景。 例如:页面加载时,同时请求多个非核心接口(广告、推荐、统计),无论哪个接口失败,都要展示其他接口的返回结果。
3. Promise.race():「谁先完成,就用谁的结果(无论成败)」
功能说明
- 接收一个 Promise 可迭代对象。
- 「竞赛」模式:只要有一个 Promise 率先完成(无论成功
fulfilled还是失败rejected),就立即采用该 Promise 的结果。 - 返回的新 Promise 状态和率先完成的那个 Promise 一致:
- 率先完成的是成功,返回的 Promise 就成功。
- 率先完成的是失败,返回的 Promise 就失败。
- 只返回第一个完成的 Promise 的结果,忽略其他所有后续完成的 Promise。
代码示例
javascript
// 定义三个模拟 Promise(执行速度不同)
const p1 = new Promise((resolve) => setTimeout(() => resolve("结果1"), 1000)); // 1秒后成功
const p2 = new Promise((resolve, reject) => setTimeout(() => reject("出错了!"), 500)); // 0.5秒后失败
const p3 = Promise.resolve("结果3"); // 立即成功
// 场景1:p3 立即完成,返回 p3 的成功结果
Promise.race([p1, p2, p3])
.then((result) => {
console.log("race 成功结果:", result); // 输出:race 成功结果: 结果3
})
.catch((error) => {
console.log("race 失败结果:", error);
});
// 场景2:注释 p3,p2 先完成(失败),返回 p2 的失败结果
// Promise.race([p1, p2])
// .then((result) => {
// console.log("race 成功结果:", result);
// })
// .catch((error) => {
// console.log("race 失败结果:", error); // 输出:race 失败结果: 出错了!
// });
适用场景
需要给异步操作设置超时时间,或者只需要获取多个异步操作中「最快返回」的结果的场景。
例如:接口请求时,超过5秒还未返回,就提示「请求超时」(用 Promise.race 包装接口 Promise 和一个 5 秒后失败的 Promise)。
4. Promise.any():「谁先成功,就用谁的结果;全部失败才失败」
功能说明
- 接收一个 Promise 可迭代对象。
- 「容错竞赛」模式:忽略失败的 Promise,只等待第一个成功的 Promise。
- 返回的新 Promise 状态规则:
- 只要有一个 Promise 成功,就立即采用该成功结果(返回成功的 Promise)。
- 只有所有 Promise 都失败,才会返回失败的 Promise,失败原因是一个
AggregateError(包含所有失败原因的集合)。
- 对比
race:any只关心「第一个成功」,race关心「第一个完成(无论成败)」。
代码示例
javascript
const p1 = new Promise((resolve) => setTimeout(() => resolve("结果1"), 1000)); // 1秒后成功
const p2 = new Promise((resolve, reject) => setTimeout(() => reject("出错了!"), 500)); // 0.5秒后失败
const p3 = Promise.reject("又出错了!"); // 立即失败
// 场景1:p2、p3 先失败,最终 p1 成功,返回 p1 的结果
Promise.any([p1, p2, p3])
.then((result) => {
console.log("any 成功结果:", result); // 输出:any 成功结果: 结果1
})
.catch((error) => {
console.log("any 失败结果:", error);
console.log("any 所有失败原因:", error.errors); // 查看所有失败原因
});
// 场景2:所有 Promise 都失败,返回 AggregateError
// const p4 = Promise.reject("错误1");
// const p5 = Promise.reject("错误2");
// Promise.any([p4, p5])
// .then((result) => {
// console.log("any 成功结果:", result);
// })
// .catch((error) => {
// console.log("any 失败结果:", error); // 输出:AggregateError: All promises were rejected
// console.log("any 所有失败原因:", error.errors); // 输出:['错误1', '错误2']
// });
适用场景
需要从多个异步操作中获取「任意一个成功结果」,且希望容错(部分操作失败不影响)的场景。 例如:请求同一个接口的多个备用节点(主节点、备用节点1、备用节点2),只要有一个节点返回成功,就使用该结果,无需等待其他节点。
核心对比表格
为了方便你快速记忆,整理了关键属性对比表:
| 方法名 | 成功条件 | 失败条件 | 结果格式 | 快速失败 | 适用场景 |
|---|---|---|---|---|---|
Promise.all | 所有 Promise 都成功 | 任意一个 Promise 失败 | 成功结果数组(顺序对应) | 是 | 需所有异步操作完成才能继续 |
Promise.allSettled | 永远成功(无论传入结果) | 无(返回的 Promise 永不失败) | 状态对象数组(包含成功/失败) | 否 | 需获取所有异步操作的完整结果 |
Promise.race | 第一个完成的 Promise 成功 | 第一个完成的 Promise 失败 | 第一个完成的 Promise 结果 | 是 | 异步操作超时控制、取最快结果 |
Promise.any | 任意一个 Promise 成功(第一个成功) | 所有 Promise 都失败 | 第一个成功的 Promise 结果 | 否(忽略失败) | 多备用节点请求、容错取成功结果 |
总结
- 需全部成功用
all,需全部结果(无论成败)用allSettled。 - 需最快完成(无论成败)用
race,需最快成功(容错失败)用any。 - 四个方法返回的都是新 Promise,且结果顺序(除
race/any只取第一个外)与传入 Promise 数组顺序一致。