ES7 Promise.allSettled 方法的使用和实现,解决 Promise 并发操作中的难点

Promise 是 JavaScript 中一种常用的处理异步操作的方式,而 Promise.all 方法则是在多个 Promise 并发执行时使用的工具函数。然而,Promise.all 方法会在任意一个 Promise 被 rejected 时,立即终止所有的并发操作,并返回一个 rejected 状态的 Promise 实例。这限制了在并发操作中的容错性。ES7 引入的 Promise.allSettled 方法可以很好地解决这个问题。

什么是 Promise.allSettled 方法

Promise.allSettled 方法是在 ES7 规范中引入的,通过并发执行多个 Promise,并对所有结果进行处理。与 Promise.all 方法不同的是,Promise.allSettled 方法会等待所有 Promise 完成,并且不会在其中任意一个 Promise 被 rejected 时停止执行。返回的结果为一个数组,数组的每一项都包含一个对象,该对象有两个属性:status 和 value(或 reason)。

  • status: 表示 Promise 的状态,有两个可能的值:“fulfilled” 或 “rejected”
  • value(或 reason): 如果 Promise 状态是 “fulfilled”,则 value 表示 Promise 的 resolve 值,如果是 “rejected”,则 reason 表示 Promise 的 reject 值。

Promise.allSettled 方法的使用

使用 Promise.allSettled 方法可以很方便地处理多个并发操作,并且在所有操作完成后执行后续的操作。下面是一个例子:

const promises = [
  Promise.resolve("success"),
  Promise.reject("failure"),
  Promise.resolve("success again")
];

Promise.allSettled(promises).then(results => {
  for (const result of results) {
    console.log(`${result.status}: ${result.value}`);
  }
});

运行以上代码会输出:

fulfilled: success
rejected: failure
fulfilled: success again

实现 Promise.allSettled 方法

如果你想了解具体实现方式,可以参考以下的代码:

Promise.allSettled = function(promises) {
  return new Promise(resolve => {
    const results = [];
    let count = promises.length;

    if (count === 0) {
      resolve(results);
    }

    function handleResult(index, status, value) {
      results[index] = { status, value };

      if (--count === 0) {
        resolve(results);
      }
    }

    for (let i = 0; i < promises.length; i++) {
      promises[i].then(value => {
        handleResult(i, 'fulfilled', value);
      }, reason => {
        handleResult(i, 'rejected', reason);
      });
    }
  });
};

实现方式很简单,通过一个计数器 count 维护并发操作的数量,并在每个 Promise 完成后更新计数器的值。对于每个完成的 Promise,将其结果存入 results 数组。最后,当计数器的值减为 0 时,调用 resolve 并传入 results 数组。对于 Promise 的状态变动,通过 Promise 对象的 then 方法实现。

总结

ES7 引入的 Promise.allSettled 方法为 JavaScript 的 Promise 提供了更好的容错性和可靠性,能在多个 Promise 并发执行时便利地处理并返回所有完成的承诺和执行结果。实现 Promise.allSettled 方法并不难,希望本文能够对你的学习和工作有所启发。

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