手写实现Promise.all、Promise.race、Promise.finally

作者:菠萝爱吃肉2024.02.16 23:18浏览量:4

简介:本文将通过代码示例,详细介绍如何手写实现Promise.all、Promise.race和Promise.finally这三个常用的Promise方法。

在JavaScript中,Promise是一种用于处理异步操作的对象。Promise.all、Promise.race和Promise.finally是Promise的三个常用方法,它们分别用于处理多个Promise的并行执行、竞争条件和最终执行。下面我们将通过代码示例,详细介绍如何手写实现这三个方法。

一、手写实现Promise.all

Promise.all方法用于同时执行多个Promise,并在所有Promise都成功时返回一个包含所有结果的数组。下面是一个简单的实现示例:

  1. function PromiseAll(promises) {
  2. return new Promise((resolve, reject) => {
  3. let results = [];
  4. let pendingCount = promises.length;
  5. for (let i = 0; i < promises.length; i++) {
  6. promises[i].then(result => {
  7. results[i] = result;
  8. pendingCount--;
  9. if (pendingCount === 0) {
  10. resolve(results);
  11. }
  12. }).catch(reject);
  13. }
  14. });
  15. }

在这个实现中,我们首先创建了一个空的数组results来存储所有Promise的结果。然后,我们遍历promises数组,对每个Promise调用then方法来处理成功的情况,将结果存储在results数组中。同时,我们使用一个变量pendingCount来跟踪还有多少个Promise尚未完成。当所有Promise都完成后,我们调用resolve方法返回结果数组。如果在执行过程中发生错误,我们调用reject方法抛出异常。

二、手写实现Promise.race

Promise.race方法用于处理多个Promise的竞争条件,即只返回第一个成功或失败的Promise。下面是一个简单的实现示例:

  1. function PromiseRace(promises) {
  2. return new Promise((resolve, reject) => {
  3. let pendingCount = promises.length;
  4. for (let i = 0; i < promises.length; i++) {
  5. promises[i].then(resolve).catch(reject).finally(() => {
  6. pendingCount--;
  7. if (pendingCount === 0) {
  8. resolve();
  9. }
  10. });
  11. }
  12. });
  13. }

在这个实现中,我们使用一个变量pendingCount来跟踪还有多少个Promise尚未完成。然后,我们遍历promises数组,对每个Promise调用then方法来处理成功的情况,或者catch方法来处理失败的情况。无论成功还是失败,我们都调用finally方法来减少pendingCount计数器。当所有Promise都完成后,我们调用resolve方法返回结果。如果在执行过程中发生错误,我们调用reject方法抛出异常。

三、手写实现Promise.finally

Promise.finally方法用于在Promise执行完毕后执行一个回调函数。下面是一个简单的实现示例:

javascript function PromiseFinally(promise, callback) { return new Promise((resolve, reject) => {\n promise.then(result => {\n callback();\n resolve(result);\n }).catch(error => {\n callback();\n reject(error);\n });\n });\n}\n在这个实现中,我们创建了一个新的Promise对象,并使用then和catch方法来处理原始Promise的成功和失败情况。无论成功还是失败,我们都调用callback回调函数。然后,我们根据原始Promise的结果调用resolve或reject方法来返回新的Promise的结果。这样,无论原始Promise是成功还是失败,我们都可以在执行完毕后执行特定的回调函数。