理解 JavaScript 中的 Promise.allSettled、Promise.all 和 Promise.race

448 阅读3分钟

在现代 JavaScript 开发中,Promise 是处理异步操作的强大工具。为了更好地管理多个异步操作,JavaScript 提供了几种方法:Promise.allSettledPromise.allPromise.race。每种方法都有其独特的行为和用途。本文将详细介绍它们的区别和使用场景。

Promise.allSettled

Promise.allSettled 方法接受一个包含多个 Promise 的数组,并返回一个新的 Promise。当所有的 Promise 都已完成(无论是成功还是失败)时,返回的 Promise 将被解决(resolved)。返回的结果是一个数组,数组中的每个元素都是一个对象,表示每个 Promise 的结果。

特点

  • 等待所有 Promise 都完成(无论是成功还是失败)。
  • 返回的结果数组包含每个 Promise 的状态和结果。

用法

const promises = [
  Promise.resolve(1),
  Promise.reject('error'),
  Promise.resolve(3)
];

Promise.allSettled(promises).then((results) => {
  results.forEach((result) => {
    if (result.status === 'fulfilled') {
      console.log('Fulfilled:', result.value);
    } else {
      console.log('Rejected:', result.reason);
    }
  });
});

输出

Fulfilled: 1
Rejected: error
Fulfilled: 3

适用场景

Promise.allSettled 适用于需要等待所有异步操作完成后再进行下一步操作的场景,无论这些操作是成功还是失败。例如,批量处理多个 API 请求,并在所有请求完成后统一处理结果。

Promise.all

Promise.all 方法接受一个包含多个 Promise 的数组,并返回一个新的 Promise。当所有的 Promise 都成功时,返回的 Promise 将被解决(resolved),并返回一个包含所有结果的数组。如果其中任何一个 Promise 失败,返回的 Promise 将被拒绝(rejected),并返回第一个失败的 Promise 的原因。

特点

  • 等待所有 Promise 都成功。
  • 如果有任何一个 Promise 失败,返回的 Promise 将立即被拒绝。

用法

const promises = [
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.resolve(3)
];

Promise.all(promises).then((results) => {
  console.log('All resolved:', results);
}).catch((error) => {
  console.log('One of the promises failed:', error);
});

输出

All resolved: [1, 2, 3]

如果有一个 Promise 失败:

const promises = [
  Promise.resolve(1),
  Promise.reject('error'),
  Promise.resolve(3)
];

Promise.all(promises).then((results) => {
  console.log('All resolved:', results);
}).catch((error) => {
  console.log('One of the promises failed:', error);
});

输出

One of the promises failed: error

适用场景

Promise.all 适用于需要所有异步操作都成功才能继续下一步操作的场景。例如,加载多个资源文件,只有在所有文件都成功加载后才开始渲染页面。

Promise.race

Promise.race 方法接受一个包含多个 Promise 的数组,并返回一个新的 Promise。当第一个 Promise 完成(无论是成功还是失败)时,返回的 Promise 将被解决(resolved)或拒绝(rejected),并返回第一个完成的 Promise 的结果。

特点

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

用法

const promises = [
  new Promise((resolve) => setTimeout(resolve, 100, 'one')),
  new Promise((resolve) => setTimeout(resolve, 200, 'two')),
  new Promise((resolve) => setTimeout(resolve, 300, 'three'))
];

Promise.race(promises).then((result) => {
  console.log('First resolved:', result);
}).catch((error) => {
  console.log('First rejected:', error);
});

输出

First resolved: one

如果有一个 Promise 失败得更快:

const promises = [
  new Promise((resolve) => setTimeout(resolve, 200, 'two')),
  new Promise((resolve, reject) => setTimeout(reject, 100, 'error')),
  new Promise((resolve) => setTimeout(resolve, 300, 'three'))
];

Promise.race(promises).then((result) => {
  console.log('First resolved:', result);
}).catch((error) => {
  console.log('First rejected:', error);
});

输出

First rejected: error

适用场景

Promise.race 适用于需要第一个完成的异步操作结果的场景。例如,多个数据源的竞赛,获取最快返回的数据。

总结

  • Promise.allSettled:等待所有 Promise 都完成(无论是成功还是失败),返回每个 Promise 的状态和结果。适用于需要处理所有异步操作结果的场景。
  • Promise.all:等待所有 Promise 都成功,如果有任何一个 Promise 失败,返回的 Promise 将被拒绝。适用于需要所有异步操作都成功才能继续的场景。
  • Promise.race:返回第一个完成的 Promise 的结果(无论是成功还是失败)。适用于需要第一个完成的异步操作结果的场景。

选择哪种方法取决于你的具体需求和应用场景。希望这篇文章能帮助你更好地理解和使用这些 Promise 方法,从而更高效地处理异步操作。