Promise.all
是 JavaScript 中处理多个 Promise 并行执行的重要方法,它可以将多个异步操作组合成一个单一的 Promise,便于统一处理成功或失败的结果。以下是详细说明:
一、基本概念
Promise.all(iterable)
接收一个可迭代对象(如数组),并返回一个新的 Promise 对象:
- 所有 Promise 成功:当所有输入的 Promise 都成功完成(resolve)时,返回的 Promise 才会成功,结果为所有 Promise 结果的数组(按输入顺序排列)。
- 任一 Promise 失败:只要有一个 Promise 失败(reject),返回的 Promise 会立即失败,错误信息为第一个失败的 Promise 的原因。
二、语法
const promiseAll = Promise.all([promise1, promise2, ...]);
promiseAll.then(results => {// 所有 Promise 成功后的处理
}).catch(error => {// 任一 Promise 失败后的处理
});
三、使用示例
1. 所有 Promise 成功
const p1 = Promise.resolve(1);
const p2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const p3 = fetch('https://api.example.com/data');Promise.all([p1, p2, p3]).then(([result1, result2, result3]) => {console.log(result1); // 1console.log(result2); // 2console.log(result3); // fetch 请求的响应});
2. 任一 Promise 失败
const p1 = Promise.resolve(1);
const p2 = Promise.reject(new Error('Failed!'));
const p3 = new Promise((resolve) => setTimeout(resolve, 1000));Promise.all([p1, p2, p3]).catch(error => {console.error(error); // Error: Failed!});
一旦 p2
失败,Promise.all
立即终止,不会等待 p3
完成。
四、参数处理
- 非 Promise 值:如果参数包含非 Promise 值(如数字、字符串),
Promise.all
会将其转换为已解决的 Promise。Promise.all([1, Promise.resolve(2), 'hello']).then(results => {console.log(results); // [1, 2, 'hello']});
五、注意事项
-
快速失败(Fail-Fast)
只要有一个 Promise 失败,Promise.all
会立即进入catch
,不再等待其他未完成的 Promise。但注意:已启动的异步操作仍会执行,只是结果被忽略。 -
结果顺序
返回的结果数组顺序与输入的 Promise 顺序一致,与完成顺序无关。 -
内存问题
如果处理大量 Promise,需注意内存占用。例如,同时发起 1000 个网络请求可能导致性能问题。
六、适用场景
- 同时发起多个无依赖的异步请求(如多个 API 调用)。
- 需要所有异步操作完成后再进行下一步处理(如数据聚合)。
- 并行处理任务,提升执行效率。
七、替代方案
-
Promise.allSettled
等待所有 Promise 完成(无论成功或失败),返回每个 Promise 的状态和结果。Promise.allSettled([p1, p2]).then(results => {results.forEach(result => {if (result.status === 'fulfilled') {console.log(result.value);} else {console.error(result.reason);}});});
-
Promise.any
当任意一个 Promise 成功时立即返回,忽略失败。 -
Promise.race
当任意一个 Promise 完成(无论成功或失败)时立即返回。
八、结合 Async/Await
async function handlePromises() {try {const results = await Promise.all([asyncTask1(), asyncTask2()]);console.log(results);} catch (error) {console.error(error);}
}
总结
Promise.all
是处理多个并行异步操作的强大工具,但在使用时需注意错误处理和性能问题。根据场景选择合适的并发控制方法(如分批次处理大量 Promise)。