返回

Promise.all与Promise.allSettled的对比和正确使用姿势

前端

巧用Promise.all和Promise.allSettled应对异步编程的挑战

在JavaScript中,Promise是处理异步编程的利器。当我们需要等待多个异步操作同时完成时,Promise.allPromise.allSettled 可以大显身手。本文将深入探讨这两者的异同,助你应对异步编程的挑战。

语法:捕捉异步操作的结果

Promise.all(iterable) :接受可迭代对象,其中每个元素都是一个Promise。一旦所有传入的Promise完成,它返回一个新的Promise。若所有Promise成功,则新Promise解析为包含各个结果的数组;若有任何一个Promise被拒绝,则新Promise立即被拒绝,原因是第一个被拒绝的Promise的原因。

Promise.allSettled(iterable) :与Promise.all类似,但它无论传入的Promise是否被拒绝,始终解析。它返回一个数组,其中每个元素是一个对象,包含Promise的状态和结果。

执行顺序:控制并发性

Promise.all :按传入的顺序执行Promise。

Promise.allSettled :并发执行传入的Promise。

返回值:解析后的结果

Promise.all :所有Promise都成功解析,则解析为包含各个结果的数组;否则,被拒绝,原因是第一个被拒绝的Promise的原因。

Promise.allSettled :始终解析,返回一个包含Promise状态和结果对象的数组。

适用场景:根据需求选择

Promise.all

  • 需要等待所有异步操作同时完成
  • 关心所有异步操作是否都成功完成
  • 需要将所有异步操作的结果组合成一个数组

Promise.allSettled

  • 需要等待所有异步操作同时完成,但不关心是否都成功
  • 需要获取所有异步操作的结果,即使有被拒绝的

代码示例:实践出真知

// Promise.all示例
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('第一个Promise成功'), 1000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('第二个Promise成功'), 2000);
});
const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => reject('第三个Promise失败'), 3000);
});

Promise.all([promise1, promise2, promise3])
  .then((results) => console.log(results)) // ['第一个Promise成功', '第二个Promise成功', '第三个Promise失败']
  .catch((error) => console.error(error)); // '第三个Promise失败'

// Promise.allSettled示例
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('第一个Promise成功'), 1000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('第二个Promise成功'), 2000);
});
const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => reject('第三个Promise失败'), 3000);
});

Promise.allSettled([promise1, promise2, promise3])
  .then((results) => console.log(results)); 
  // [{status: 'fulfilled', value: '第一个Promise成功'}, 
  // {status: 'fulfilled', value: '第二个Promise成功'}, 
  // {status: 'rejected', reason: '第三个Promise失败'}]

常见问题解答

  1. 两者有什么共同点?

    • 都是处理多个异步操作的Promise方法
    • 都返回一个Promise对象
  2. 两者最大的区别是什么?

    • Promise.all关心所有Promise是否都成功,而Promise.allSettled不关心
  3. 什么时候应该使用Promise.all?

    • 当我们需要等待所有异步操作都成功完成时
  4. 什么时候应该使用Promise.allSettled?

    • 当我们需要等待所有异步操作完成,无论是否成功
  5. 如何处理被拒绝的Promise?

    • Promise.all会立即被拒绝,原因是第一个被拒绝的Promise的原因;Promise.allSettled会返回一个包含被拒绝Promise状态和原因的对象