乐闻世界logo
搜索文章和话题

Promise.all() 和 Promise.race() 的区别是什么?

2月22日 14:07

Promise.all() 和 Promise.race() 是 Promise 提供的两个重要的静态方法,它们用于处理多个 Promise 的并行执行,但行为和用途完全不同。

Promise.all()

基本概念

Promise.all() 接收一个 Promise 数组作为参数,返回一个新的 Promise。这个新的 Promise 会在所有输入的 Promise 都成功完成时才成功,返回的结果是所有 Promise 结果组成的数组(顺序与输入顺序一致)。如果任何一个 Promise 失败,Promise.all() 会立即失败,返回第一个失败的 Promise 的错误。

使用场景

  • 需要同时发起多个独立的请求,并等待所有请求都完成
  • 多个异步操作之间存在依赖关系,需要所有结果都准备好后才能继续

示例代码

javascript
const promise1 = fetch('/api/user'); const promise2 = fetch('/api/posts'); const promise3 = fetch('/api/comments'); Promise.all([promise1, promise2, promise3]) .then(responses => { // 所有请求都成功 return Promise.all(responses.map(r => r.json())); }) .then(data => { console.log('所有数据:', data); }) .catch(error => { console.error('某个请求失败:', error); });

特点

  1. 并行执行: 所有 Promise 同时开始执行
  2. 顺序保证: 结果数组顺序与输入顺序一致
  3. 快速失败: 任何一个失败,整体立即失败
  4. 空数组: 如果传入空数组,立即返回成功

Promise.race()

基本概念

Promise.race() 同样接收一个 Promise 数组,返回一个新的 Promise。这个新的 Promise 会在第一个 Promise 完成(无论成功或失败)时立即完成,并返回第一个完成的 Promise 的结果或错误。

使用场景

  • 设置超时机制
  • 从多个数据源获取数据,使用最快返回的结果
  • 竞争条件处理

示例代码

javascript
// 超时示例 const fetchData = fetch('/api/data'); const timeout = new Promise((_, reject) => { setTimeout(() => reject(new Error('请求超时')), 5000); }); Promise.race([fetchData, timeout]) .then(response => console.log('数据获取成功')) .catch(error => console.error(error)); // 多数据源竞争示例 const source1 = fetch('https://api1.example.com/data'); const source2 = fetch('https://api2.example.com/data'); const source3 = fetch('https://api3.example.com/data'); Promise.race([source1, source2, source3]) .then(response => response.json()) .then(data => console.log('最快的数据源:', data));

特点

  1. 快速返回: 返回第一个完成的结果
  2. 状态继承: 成功或失败取决于第一个完成的 Promise
  3. 不确定性: 哪个 Promise 先完成是不确定的
  4. 空数组: 如果传入空数组,Promise 永远处于 pending 状态

对比总结

特性Promise.all()Promise.race()
完成条件所有 Promise 都成功第一个 Promise 完成
失败条件任何一个 Promise 失败第一个 Promise 失败
返回结果所有结果的数组第一个完成的结果
使用场景需要所有结果需要最快结果
执行方式并行执行并行执行

其他相关方法

Promise.allSettled()

ES2020 新增,等待所有 Promise 完成(无论成功或失败),返回每个 Promise 的状态和结果:

javascript
Promise.allSettled([promise1, promise2, promise3]) .then(results => { results.forEach(result => { if (result.status === 'fulfilled') { console.log('成功:', result.value); } else { console.log('失败:', result.reason); } }); });

Promise.any()

ES2021 新增,返回第一个成功的 Promise,如果所有 Promise 都失败,返回 AggregateError:

javascript
Promise.any([promise1, promise2, promise3]) .then(result => console.log('第一个成功:', result)) .catch(error => console.log('全部失败:', error));

实际应用建议

  1. 使用 Promise.all(): 当需要所有数据都准备好时,如加载多个必需的资源
  2. 使用 Promise.race(): 当只需要最快的结果时,如设置超时或从多个镜像源获取数据
  3. 使用 Promise.allSettled(): 当需要知道每个操作的结果,即使某些失败
  4. 使用 Promise.any(): 当只需要一个成功的结果,如从多个备份服务器获取数据
标签:Promise