ES9 中新增的 Promise.all() 方法的不足与替代方案

ES9 中 Promise.all() 方法介绍

在 ES6 中,Promise.all() 方法被引入作为 Promise API 的一部分,它是一种实现并行异步操作的方法,可以同时处理多个 Promise 对象。

Promise.all() 方法接收一个 Promise 对象数组作为参数,该方法会返回一个 Promise 实例。当 Promise.all() 方法中的 Promise 对象数组中的所有 Promise 对象都 resolve 或者其中至少一个 Promise 对象 reject 的时候,Promise.all() 方法返回的 Promise 实例才会 resolve 或者 reject。

在 ES9 中,Promise.all() 方法被进一步加强,它可以接收一个可迭代对象 (如数组,Map,Set 等)。同时,Promise.all() 方法支持在 Promise 对象数组中添加Promise-like对象,即拥有 .then() 方法的普通对象。

const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3]).then(values => {
  console.log(values); // [1, 2, 3]
});

Promise.all() 方法的不足

然而,Promise.all() 方法也存在一些不足之处。

当 Promise 对象数组中的某个 Promise 对象 reject 时,Promise.all() 方法将立即返回而不执行剩余 Promise 对象的操作。这导致 Promise.all() 方法不够灵活,因为所有 Promise 对象都必须成功才能返回结果。

const promise1 = Promise.resolve(1);
const promise2 = Promise.reject("reject");
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3]).then(values => {
  console.log(values);
}).catch(error => {
  console.log(error); // "reject"
});

对于以上代码,控制台只会输出 "reject",而不会输出成功的 Promise 对象值 1 和 3,这大大限制了 Promise.all() 的使用场景。

Promise.allSettled() 方法

为了解决 Promise.all() 方法的不足,ES11 推出了 Promise.allSettled() 方法。该方法一定会等到所有 Promise 对象操作结束后,返回一个包含所有操作结果(成功和失败)的对象数组。

Promise.allSettled() 方法返回的每个对象都包含以下两个属性:

  • status: "fulfilled" 或 "rejected",表示对应的 Promise 对象操作的状态。
  • value: 对应的 Promise 对象操作的值(成功时)或异常对象(失败时)。
const promise1 = Promise.resolve(1);
const promise2 = Promise.reject("reject");
const promise3 = Promise.resolve(3);
Promise.allSettled([promise1, promise2, promise3]).then(results => {
  console.log(results);
});

以上代码输出结果如下:

[
  { status: "fulfilled", value: 1 },
  { status: "rejected", reason: "reject" },
  { status: "fulfilled", value: 3 }
]

Promise.any() 方法

ES2021 引入了 Promise.any() 方法,与 Promise.all() 方法的作用相反,即当 Promise 对象数组中的所有 Promise 对象都 reject 时,Promise.any() 方法才会 reject。

与 Promise.all() 方法不同的是,Promise.any() 方法一旦发现第一个成功的 Promise 对象,就会立即返回该 Promise 对象的值,而不会等待所有 Promise 对象都成功才返回结果。如果没有任何一个 Promise 对象成功,则返回一个 AggregateError 异常对象,包含所有的失败结果。

const promise1 = new Promise((resolve, reject) => setTimeout(() => reject("reject 1"), 1000));
const promise2 = new Promise((resolve, reject) => setTimeout(() => reject("reject 2"), 500));
const promise3 = new Promise((resolve, reject) => setTimeout(() => resolve("resolve 3"), 2000));

Promise.any([promise1, promise2, promise3]).then(result => {
  console.log(result);  // "resolve 3"
}).catch(error => {
  console.log(error);  // AggregateError: All Promises were rejected
  console.log(error.errors); // ["reject 1", "reject 2"]
});

以上代码输出结果如下:

"resolve 3"

总结

ES9 中 Promise.all() 方法是一种实现并行异步操作的方法,具有一定的限制。

为了解决 Promise.all() 的限制,ES11 推出了 Promise.allSettled() 方法,它可以返回所有 Promise 对象操作结果,不受 Promise 状态的限制。

同时,ES2021 引入了 Promise.any() 方法,与 Promise.all() 的作用相反,即在所有 Promise 对象都失败时才 reject,而不是所有 Promise 对象都成功时才 resolve。

在实际开发中,根据具体业务场景选择合适的方法,是提高程序效率和开发效率的关键。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65937902eb4cecbf2d82f183


纠错反馈