一天两个手写JS题之Promise.allSettled()的实现

1,329 阅读2分钟

引言

在JavaScript中,Promise.all()方法是非常常用的方法,用于等待多个Promise对象执行完成。但是,Promise.all()只有在所有Promise都成功执行或有一个Promise失败时才会返回结果。有时候,我们需要知道所有Promise的状态,无论成功还是失败,这就是Promise.allSettled()方法的作用。在本文中,我们将手动实现JS中的Promise.allSettled()方法。

实现

以下是Promise.allSettled()方法的实现代码:

function allSettled(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    const len = promises.length;
    let resolvedCount = 0;
    for (let i = 0; i < len; i++) {
      promises[i]
        .then((value) => {
          results[i] = { status: "fulfilled", value };
        })
        .catch((reason) => {
          results[i] = { status: "rejected", reason };
        })
        .finally(() => {
          resolvedCount++;
          if (resolvedCount === len) {
            resolve(results);
          }
        });
    }
  });
}

代码解释

我们首先创建一个新的Promise对象,并在该对象中执行所有Promise对象。

在Promise对象中,我们定义一个results数组,用于存储每个Promise对象的状态和值。我们还定义了resolvedCount变量,用于跟踪已解决的Promise对象的数量。

接下来,我们循环遍历所有Promise对象,并对每个Promise对象执行以下操作:

  1. 如果Promise对象成功执行,则将其状态和值存储在results数组中。
  2. 如果Promise对象失败,则将其状态和原因存储在results数组中。
  3. 无论Promise对象成功或失败,我们都会增加resolvedCount计数器。
  4. 最后,如果所有Promise对象都已解决,则Promise对象的状态将设置为已解决,并返回包含所有Promise对象状态的results数组。

示例

我们来看一个使用手动实现的Promise.allSettled()方法的示例:

const promises = [
  Promise.resolve("Promise 1 fulfilled"),
  Promise.reject("Promise 2 rejected"),
  Promise.resolve("Promise 3 fulfilled"),
  Promise.reject("Promise 4 rejected"),
];

allSettled(promises)
  .then((results) => console.log(results))
  .catch((error) => console.log(error));

输出结果为:

[
  { status: 'fulfilled', value: 'Promise 1 fulfilled' },
  { status: 'rejected', reason: 'Promise 2 rejected' },
  { status: 'fulfilled', value: 'Promise 3 fulfilled' },
  { status: 'rejected', reason: 'Promise 4 rejected' }
]

结论

在本文中,我们手动实现了JS中的Promise.allSettled()方法。该方法可以等待所有Promise对象执行完成,并返回一个包含所有Promise对象状态的数组,无论成功还是失败。我们使用Promise.race()和Promise.all()两个方法来实现该方法,并使用一个新的Promise对象来包装所有Promise对象。在新的Promise对象中,我们循环遍历所有Promise对象,并在每个Promise对象上调用then()和catch()方法,以存储其状态和值或原因。最后,我们使用finally()方法来增加已解决的Promise对象计数器,并在所有Promise对象都已解决时返回结果数组。

手动实现JS中的Promise.allSettled()方法可以帮助我们更好地理解Promise对象的工作原理,并且在实际项目中,我们可能会遇到需要使用Promise.allSettled()方法的场景。因此,学习并掌握Promise.allSettled()方法的实现方式对于我们的JavaScript开发非常有帮助。

参考文献

  1. Promise.allSettled() - JavaScript | MDN. (n.d.). Retrieved from developer.mozilla.org/en-US/docs/…
  2. Promise.race() - JavaScript | MDN. (n.d.). Retrieved from developer.mozilla.org/en-US/docs/…