返回

从零构建 Promise,逐一剖析then、all、race、resolve、reject、finally等核心方法

前端

Promise 的基本原理

Promise 是一个对象,它表示一个异步操作的最终完成或失败的状态。当一个 Promise 被创建时,它会立即处于 pending 状态。当异步操作完成时,Promise 会被解析(resolved)或拒绝(rejected)。一旦 Promise 被解析或拒绝,它的状态就无法再改变。

Promise 的核心方法

Promise 提供了几个核心方法,用于处理异步操作和获取异步操作的结果。这些方法包括:

  • then():then() 方法用于在 Promise 被解析或拒绝时执行相应的回调函数。
  • all():all() 方法用于等待多个 Promise 都被解析,然后执行回调函数。
  • race():race() 方法用于等待多个 Promise 中的第一个被解析或拒绝,然后执行回调函数。
  • resolve():resolve() 方法用于将 Promise 的状态解析为已完成。
  • reject():reject() 方法用于将 Promise 的状态拒绝为已失败。
  • finally():finally() 方法用于在 Promise 被解析或拒绝后执行回调函数。

手写 Promise

现在,让我们从零构建一个基础版的 Promise。

class Promise {
  constructor(executor) {
    this.state = "pending"; // Promise 的初始状态
    this.value = undefined; // Promise 的值
    this.reason = undefined; // Promise 的原因
    this.onFulfilledCallbacks = []; // Promise 被解析时要执行的回调函数队列
    this.onRejectedCallbacks = []; // Promise 被拒绝时要执行的回调函数队列

    // 执行器函数,用于执行异步操作并解析或拒绝 Promise
    try {
      executor(
        // resolve() 函数,用于将 Promise 的状态解析为已完成
        (value) => {
          this.resolve(value);
        },
        // reject() 函数,用于将 Promise 的状态拒绝为已失败
        (reason) => {
          this.reject(reason);
        }
      );
    } catch (error) {
      // 如果执行器函数抛出错误,则将 Promise 的状态拒绝为已失败
      this.reject(error);
    }
  }

  // 将 Promise 的状态解析为已完成
  resolve(value) {
    if (this.state !== "pending") {
      return;
    }

    this.state = "fulfilled";
    this.value = value;

    // 执行所有已注册的 onFulfilled 回调函数
    this.onFulfilledCallbacks.forEach((callback) => {
      callback(value);
    });
  }

  // 将 Promise 的状态拒绝为已失败
  reject(reason) {
    if (this.state !== "pending") {
      return;
    }

    this.state = "rejected";
    this.reason = reason;

    // 执行所有已注册的 onRejected 回调函数
    this.onRejectedCallbacks.forEach((callback) => {
      callback(reason);
    });
  }

  // then() 方法
  then(onFulfilled, onRejected) {
    // 返回一个新的 Promise
    return new Promise((resolve, reject) => {
      // 如果 Promise 已经解析,则立即执行 onFulfilled 回调函数
      if (this.state === "fulfilled") {
        setTimeout(() => {
          try {
            const value = onFulfilled(this.value);
            resolve(value);
          } catch (error) {
            reject(error);
          }
        }, 0);
        return;
      }

      // 如果 Promise 已经拒绝,则立即执行 onRejected 回调函数
      if (this.state === "rejected") {
        setTimeout(() => {
          try {
            const reason = onRejected(this.reason);
            reject(reason);
          } catch (error) {
            reject(error);
          }
        }, 0);
        return;
      }

      // 如果 Promise 仍然处于 pending 状态,则将 onFulfilled 和 onRejected 回调函数添加到队列中
      this.onFulfilledCallbacks.push((value) => {
        setTimeout(() => {
          try {
            const value = onFulfilled(value);
            resolve(value);
          } catch (error) {
            reject(error);
          }
        }, 0);
      });
      this.onRejectedCallbacks.push((reason) => {
        setTimeout(() => {
          try {
            const reason = onRejected(reason);
            reject(reason);
          } catch (error) {
            reject(error);
          }
        }, 0);
      });
    });
  }

  // all() 方法
  static all(promises) {
    return new Promise((resolve, reject) => {
      // 计数器,用于跟踪已解析的 Promise 的数量
      let count = 0;
      // 已解析的 Promise 的值
      const values = [];

      // 遍历所有 Promise
      promises.forEach((promise, index) => {
        // then() 方法,用于处理 Promise 的解析或拒绝
        promise.then(
          (value) => {
            // 将已解析的 Promise 的值添加到 values 数组中
            values[index] = value;

            // 计数器加 1
            count++;

            // 如果所有 Promise 都已解析,则将 values 数组作为参数解析当前 Promise
            if (count === promises.length) {
              resolve(values);
            }
          },
          (reason) => {
            // 如果其中一个 Promise 被拒绝,则立即拒绝当前 Promise
            reject(reason);
          }
        );
      });
    });
  }

  // race() 方法
  static race(promises) {
    return new Promise((resolve, reject) => {
      // 遍历所有 Promise
      promises.forEach((promise) => {
        // then() 方法,用于处理 Promise 的解析或拒绝
        promise.then(
          (value) => {
            // 如果当前 Promise 尚未被解析或拒绝,则立即解析当前 Promise
            if (this.state === "pending") {
              resolve(value);
            }
          },
          (reason) => {
            // 如果当前 Promise 尚未被解析或拒绝,则立即拒绝当前 Promise
            if (this.state === "pending") {
              reject(reason);
            }
          }
        );
      });
    });
  }

  // finally() 方法
  finally(onFinally) {
    // 返回一个新的 Promise
    return new Promise((resolve, reject) => {
      // then() 方法,用于处理当前 Promise 的解析或拒绝
      this.then(
        (value) => {
          // 执行 onFinally 回调函数
          onFinally();

          // 解析新的 Promise
          resolve(value);
        },
        (reason) => {
          // 执行 onFinally 回调函数
          onFinally();

          // 拒绝新的 Promise
          reject(reason);
        }
      );
    });
  }
}

结语

通过本文,您已经了解了 Promise 的基本原理和核心方法,并能够从零构建一个基础版的 Promise。希望这些知识能够帮助您在自己的项目中熟练使用 Promise,以实现异步编程。