云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

Promise.all() 并行处理多个异步任务

jxf315 2025-05-30 15:34:23 教程文章 4 ℃

Promise.all() 是 JavaScript 中用于并行处理多个异步任务的一个非常强大的方法。它允许同时运行多个 Promise,并在所有任务都成功完成时返回一个包含所有结果的数组。如果其中任何一个任务失败(被拒绝),Promise.all() 会立即以失败的结果结束。


语法

Promise.all(iterable);
  • 参数
    • iterable:一个可迭代对象(如数组),其元素是 Promise 或其他值。
  • 返回值
    • 返回一个新的 Promise
      • 如果所有 Promise 都成功完成,则返回一个按顺序排列的结果数组。
      • 如果任意一个 Promise 被拒绝,则返回第一个被拒绝的错误。

使用场景与示例

1. 基本用法

假设我们有多个异步任务需要并行执行,并在所有任务完成后处理结果:

const task1 = Promise.resolve(1);
const task2 = Promise.resolve(2);
const task3 = Promise.resolve(3);

Promise.all([task1, task2, task3])
  .then(results => {
    console.log(results); // 输出: [1, 2, 3]
  })
  .catch(error => {
    console.error('Error:', error);
  });

2. 并行请求数据

假设我们需要从多个 API 获取数据,并等待所有数据加载完成后再进行处理:

const fetchUser = () => fetch('https://api.example.com/user').then(res => res.json());
const fetchPosts = () => fetch('https://api.example.com/posts').then(res => res.json());
const fetchComments = () => fetch('https://api.example.com/comments').then(res => res.json());

Promise.all([fetchUser(), fetchPosts(), fetchComments()])
  .then(([user, posts, comments]) => {
    console.log('User:', user);
    console.log('Posts:', posts);
    console.log('Comments:', comments);
  })
  .catch(error => {
    console.error('Failed to fetch data:', error);
  });

3. 处理非 Promise 值

Promise.all() 的输入可以包含非 Promise 值,这些值会被直接解析为结果:

const promise1 = Promise.resolve('Hello');
const value2 = 'World';
const promise3 = 42;

Promise.all([promise1, value2, promise3])
  .then(results => {
    console.log(results); // 输出: ["Hello", "World", 42]
  });

4. 错误处理

如果其中一个 Promise 被拒绝,Promise.all() 会立即以该错误结束,并不会等待其他任务完成:

const task1 = Promise.resolve('Success');
const task2 = Promise.reject('Failure');
const task3 = Promise.resolve('Another Success');

Promise.all([task1, task2, task3])
  .then(results => {
    console.log('All tasks completed:', results);
  })
  .catch(error => {
    console.error('One task failed:', error); // 输出: One task failed: Failure
  });

5. 结合 async/await使用

通过 async/await,可以让代码更加简洁和直观:

async function fetchData() {
  try {
    const [user, posts, comments] = await Promise.all([
      fetch('https://api.example.com/user').then(res => res.json()),
      fetch('https://api.example.com/posts').then(res => res.json()),
      fetch('https://api.example.com/comments').then(res => res.json())
    ]);
    console.log('User:', user);
    console.log('Posts:', posts);
    console.log('Comments:', comments);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

fetchData();

注意事项

并行性

  • Promise.all() 中的所有任务是并行执行的,而不是串行执行。
  • 如果你需要串行执行任务,可以使用 for...of 循环结合 await

短路行为

  • 如果任意一个 Promise 被拒绝,整个 Promise.all() 会立即失败。
  • 如果你希望即使某些任务失败也能继续处理其他任务,可以考虑使用 Promise.allSettled()

性能优化

  • 对于大量任务,确保它们不会对系统资源造成过大压力(例如过多的并发网络请求)。

与其他方法的对比

方法

行为

Promise.all()

所有任务成功时返回结果数组;任意一个失败则立即失败。

Promise.race()

返回第一个完成的任务结果(无论是成功还是失败)。

Promise.allSettled()

等待所有任务完成,无论成功或失败,返回每个任务的状态和结果。

Promise.any()

返回第一个成功的任务结果;如果所有任务都失败,则抛出错误。


总结

  • Promise.all() 是处理多个异步任务的强大工具,尤其适用于需要并行执行的任务。
  • 它能显著提高效率,但需要注意错误处理和资源管理。
  • 如果需要更灵活的错误处理,可以结合 Promise.allSettled() 或其他方法。

Tags:

最近发表
标签列表