ES2021 中的 Promise.allSettled() 方法及其优劣比较 —— 值得一看

随着 JavaScript 的发展,Promise 对于处理异步操作已经变成了必用的工具之一。而在 ES2021 中引入的 Promise.allSettled() 方法则给 Promise 的使用带来了新的便利和优化。本文将详细介绍 Promise.allSettled() 方法及其优劣比较,并附上示例代码。

Promise.allSettled() 方法的作用

Promise.allSettled() 方法接受一个 Promise 对象的数组,返回一个 Promise 对象,该 Promise 对象在传入的所有 Promise 对象都已经解决或拒绝后,才会被解决。返回的 Promise 对象包含一个状态数组,其中每个值描述了对应的 Promise 对象的解决情况。

具体而言,返回的状态数组中,每个对象都会包含以下属性:

  • status:表示 Promise 对象的状态,可以是 "fulfilled"(解决)或 "rejected"(拒绝)。
  • value:如果状态为 "fulfilled",则该属性表示解决的值;否则,该属性没有定义。
  • reason:如果状态为 "rejected",则该属性表示拒绝的原因;否则,该属性没有定义。

实际使用中,Promise.allSettled() 方法常用于需要处理一组 Promise 对象的情况。例如:

const promises = [
  Promise.resolve("成功值1"),
  Promise.reject("拒绝原因2"),
  Promise.resolve("成功值3")
];

Promise.allSettled(promises).then(results => {
  results.forEach(result => {
    console.log(result.status);
    console.log(result.value);
    console.log(result.reason);
  });
});

在上述代码中,我们传入了一个包含三个 Promise 对象的数组 promises,并使用 Promise.allSettled() 方法将其包装成一个新的 Promise 对象 results,该新的 Promise 对象会在所有的 Promise 对象都已经解决或拒绝后得以解决。然后我们使用 forEach() 方法遍历 results 数组,逐个输出其状态、值和原因。

Promise.all() 方法的比较

与 Promise.all() 方法相比,Promise.allSettled() 方法相对更灵活。Promise.all() 方法中,只要有一个 Promise 对象被拒绝,就会立即返回一个拒绝状态的 Promise 对象。而在 Promise.allSettled() 方法中,所有的 Promise 对象都会被等待解决,即便其中某些对象被拒绝了。

下面是一个简单的比较示例:

const promises = [
  Promise.resolve("成功值1"),
  Promise.reject("拒绝原因2"),
  Promise.resolve("成功值3")
];

Promise.all(promises).then(results => {
  console.log("Promise.all()");
  console.log(results);
}).catch(reason => {
  console.log("Promise.all()");
  console.log(reason);
});

Promise.allSettled(promises).then(results => {
  console.log("Promise.allSettled()");
  console.log(results);
});

在上述代码中,我们使用了相同的 promises 数组来测试 Promise.all() 和 Promise.allSettled() 方法。在 Promise.all() 方法中,因为第二个 Promise 对象被拒绝,导致整个 Promise.all() 返回了一个拒绝状态的 Promise 对象。而在 Promise.allSettled() 方法中,所有的 Promise 对象都会被解决,并返回一个包含所有 Promise 对象状态的状态数组。

Promise.allSettled() 方法的兼容性

Promise.allSettled() 方法是在 ES2021 中引入的,目前还没有被所有的浏览器所支持。在写作时,部分主流的浏览器如 Chrome、Firefox、Safari 和 Edge 已经支持该方法。对于那些未支持 Promise.allSettled() 方法的浏览器,我们可以使用 Promise.all() 与 Promise.reject() 和 Promise.resolve() 等方法进行相应的兼容处理。

例如:

Promise.all([
  Promise.resolve(),
  Promise.reject(),
  Promise.resolve()
].map(p => p.catch(e => e)))
.then(results => {
  console.log("Promise.all() 兼容处理");
  console.log(results.map(r => ({
    status: r instanceof Error ? "rejected" : "fulfilled",
    value: r instanceof Error ? r.message : r
  })));
});

在上述代码中,我们首先使用 map() 方法对每个 Promise 对象进行了相应的错误处理,将其转变成了一个解决状态的 Promise 对象。然后再使用 Promise.all() 方法来返回这些 Promise 对象的值。

总结

本文详细介绍了 ES2021 中引入的 Promise.allSettled() 方法及其优劣比较,并给出了相应的示例代码。总体而言,Promise.allSettled() 方法为处理多个 Promise 对象提供了更加灵活的方式,并且兼容性较为良好。然而对于那些未支持该方法的浏览器,我们可以使用 Promise.all() 方法进行相应的兼容处理。

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