ES6手写Promise

ES6手写Promise

使用ES6 class语法实现简易版的手写Promise 实现 then 链式调用、catch、finally、和静态方法resolve,reject,注释清晰,逻辑清晰

首先定义类的成员变量

这些都是Promise中需要用的状态和回调存储

class MyPromise {
  // 定义 Promise 的三种状态
  static REJECTED = "rejected";
  static PENDING = "pending";
  static FULFILLED = "fulfilled";

  // 初始化值和状态
  value = undefined;
  status = MyPromise.PENDING;
  // 用于存储对应状态的回调函数
  onFulfilledCallbacks = [];
  onRejectedCallbacks = [];
}

然后编写构造函数

/**
   * 构造函数,用于创建一个 Promise 实例
   * @param {function} execute - 执行器函数,接受 resolve 和 reject 两个参数
   */
  constructor(execute) {
    // 定义 resolve 函数,用于改变 Promise 状态为 fulfilled
    const resolve = (value) => {
      if (this.status === MyPromise.PENDING) {
        this.value = value;
        this.status = MyPromise.FULFILLED;
        // 调用所有 fulfilled 状态的回调函数
        this.onFulfilledCallbacks.forEach((fun) => fun(value));
      }
    };
    // 定义 reject 函数,用于改变 Promise 状态为 rejected
    const reject = (value) => {
      if (this.status === MyPromise.PENDING) {
        this.value = value;
        this.status = MyPromise.REJECTED;
        // 调用所有 rejected 状态的回调函数
        this.onRejectedCallbacks.forEach((fun) => fun(value));
      }
    };

    try {
      // 执行传入的 execute 函数
      execute(resolve, reject);
    } catch (error) {
      // 捕获到错误,调用 reject
      reject(error);
    }
  }

然后实现then方法

then方法的作用是处理Promise并返回一个新的Promise对象实例,以便于进行链式调用,再返回的新Promise对象中要进行三种状态的判断。同时使用queueMicrotask 来排队执行,确保处理微任务逻辑的正确性

 /**
   * then 方法,用于处理 Promise 的结果
   * @param {function} onFulfilled - fulfilled 状态的回调函数
   * @param {function} onRejected - rejected 状态的回调函数
   * @returns {MyPromise} 返回一个新的 Promise 实例
   */
  then(onFulfilled, onRejected) {
    // 确保 onFulfilled 和 onRejected 是函数,如果不是则提供默认的实现
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };

    // 返回一个新的 Promise 实例
    return new MyPromise((resolve, reject) => {
      // 根据当前 Promise 的状态执行对应的回调函数
      if (this.status === MyPromise.FULFILLED) {
        try {
          const result = onFulfilled(this.value);
          // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
          queueMicrotask(() => {
            this.handlePromiseResult(result, resolve, reject);
          });
        } catch (error) {
          reject(error);
        }
      } else if (this.status === MyPromise.REJECTED) {
        try {
          const result = onRejected(this.value);
          // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
          queueMicrotask(() => {
            this.handlePromiseResult(result, resolve, reject);
          });
        } catch (error) {
          reject(error);
        }
      } else {
        // 如果状态是 pending,则将回调函数存储起来,等待状态改变
        this.onFulfilledCallbacks.push((value) => {
          try {
            const result = onFulfilled(value);
            // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
            queueMicrotask(() => {
              this.handlePromiseResult(result, resolve, reject);
            });
          } catch (error) {
            reject(error);
          }
        });
        this.onRejectedCallbacks.push((value) => {
          try {
            const result = onRejected(value);
            // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
            queueMicrotask(() => {
              this.handlePromiseResult(result, resolve, reject);
            });
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }

注意then方法中回调成功的result可能又为一个promise对象,这时候需要进行链式调用 编写一个函数进行判断

  /**
   * 处理 Promise 结果的方法,确保结果正确处理
   * @param {any} result - Promise 处理的结果
   * @param {function} resolve - 用于改变新的 Promise 状态为 fulfilled
   * @param {function} reject - 用于改变新的 Promise 状态为 rejected
   */
  handlePromiseResult(result, resolve, reject) {
    if (result instanceof MyPromise) {
      // 如果结果是一个 Promise,则等待其状态改变后再做处理
      result.then(resolve, reject);
    } else {
      // 否则直接改变状态为 fulfilled 并传递结果
      resolve(result);
    }
  }

整体代码

/**
 * MyPromise 类,用于实现 Promise 的基本功能
 */
class MyPromise {
  // 定义 Promise 的三种状态
  static REJECTED = "rejected";
  static PENDING = "pending";
  static FULFILLED = "fulfilled";

  // 初始化值和状态
  value = undefined;
  status = MyPromise.PENDING;
  // 用于存储对应状态的回调函数
  onFulfilledCallbacks = [];
  onRejectedCallbacks = [];

  /**
   * 构造函数,用于创建一个 Promise 实例
   * @param {function} execute - 执行器函数,接受 resolve 和 reject 两个参数
   */
  constructor(execute) {
    // 定义 resolve 函数,用于改变 Promise 状态为 fulfilled
    const resolve = (value) => {
      if (this.status === MyPromise.PENDING) {
        this.value = value;
        this.status = MyPromise.FULFILLED;
        // 调用所有 fulfilled 状态的回调函数
        this.onFulfilledCallbacks.forEach((fun) => fun(value));
      }
    };
    // 定义 reject 函数,用于改变 Promise 状态为 rejected
    const reject = (value) => {
      if (this.status === MyPromise.PENDING) {
        this.value = value;
        this.status = MyPromise.REJECTED;
        // 调用所有 rejected 状态的回调函数
        this.onRejectedCallbacks.forEach((fun) => fun(value));
      }
    };

    try {
      // 执行传入的 execute 函数
      execute(resolve, reject);
    } catch (error) {
      // 捕获到错误,调用 reject
      reject(error);
    }
  }

  /**
   * then 方法,用于处理 Promise 的结果
   * @param {function} onFulfilled - fulfilled 状态的回调函数
   * @param {function} onRejected - rejected 状态的回调函数
   * @returns {MyPromise} 返回一个新的 Promise 实例
   */
  then(onFulfilled, onRejected) {
    // 确保 onFulfilled 和 onRejected 是函数,如果不是则提供默认的实现
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };

    // 返回一个新的 Promise 实例
    return new MyPromise((resolve, reject) => {
      // 根据当前 Promise 的状态执行对应的回调函数
      if (this.status === MyPromise.FULFILLED) {
        try {
          const result = onFulfilled(this.value);
          // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
          queueMicrotask(() => {
            this.handlePromiseResult(result, resolve, reject);
          });
        } catch (error) {
          reject(error);
        }
      } else if (this.status === MyPromise.REJECTED) {
        try {
          const result = onRejected(this.value);
          // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
          queueMicrotask(() => {
            this.handlePromiseResult(result, resolve, reject);
          });
        } catch (error) {
          reject(error);
        }
      } else {
        // 如果状态是 pending,则将回调函数存储起来,等待状态改变
        this.onFulfilledCallbacks.push((value) => {
          try {
            const result = onFulfilled(value);
            // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
            queueMicrotask(() => {
              this.handlePromiseResult(result, resolve, reject);
            });
          } catch (error) {
            reject(error);
          }
        });
        this.onRejectedCallbacks.push((value) => {
          try {
            const result = onRejected(value);
            // 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
            queueMicrotask(() => {
              this.handlePromiseResult(result, resolve, reject);
            });
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }

  /**
   * 处理 Promise 结果的方法,确保结果正确处理
   * @param {any} result - Promise 处理的结果
   * @param {function} resolve - 用于改变新的 Promise 状态为 fulfilled
   * @param {function} reject - 用于改变新的 Promise 状态为 rejected
   */
  handlePromiseResult(result, resolve, reject) {
    if (result instanceof MyPromise) {
      // 如果结果是一个 Promise,则等待其状态改变后再做处理
      result.then(resolve, reject);
    } else {
      // 否则直接改变状态为 fulfilled 并传递结果
      resolve(result);
    }
  }

  /**
   * catch 方法,用于处理 Promise 的错误
   * @param {function} onRejected - rejected 状态的回调函数
   * @returns {MyPromise} 返回一个新的 Promise 实例
   */
  catch(onRejected) {
    // 使用 then 方法处理错误,并添加一个空的 then 来处理返回值
    return this.then(null, onRejected).then();
  }

  /**
   * finally 方法,用于处理 Promise 的最终逻辑,无论结果如何
   * @param {function} callback - 最终要执行的回调函数
   * @returns {MyPromise} 返回一个新的 Promise 实例
   */
  finally(callback) {
    // 无论结果如何,都执行 callback 函数,然后根据原始结果继续处理
    return this.then(
      (value) => MyPromise.resolve(callback()).then(() => value),
      (reason) =>
        MyPromise.reject(callback()).then(() => {
          throw reason;
        })
    );
  }

  /**
   * 静态方法 resolve,用于将一个值转换为 Promise 对象
   * @param {any} value - 要转换的值
   * @returns {MyPromise} 返回一个新的 Promise 实例,状态为 fulfilled
   */
  static resolve(value) {
    return new MyPromise((resolve, reject) => {
      resolve(value);
    });
  }

  /**
   * 静态方法 reject,用于创建一个拒绝状态的 Promise 对象
   * @param {any} reason - 拒绝的原因
   * @returns {MyPromise} 返回一个新的 Promise 实例,状态为 rejected
   */
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }
}

// 示例用法
const p = new MyPromise((resolve, reject) => {
  console.log("task");
  // 模拟一个异步任务,1 秒后 resolve
  setTimeout(() => {
    resolve("data");
  }, 1000);
});

// 使用 then 方法处理 Promise 的结果
p.then((res) => {
  console.log("res", res);
  // 返回一个新的 Promise,模拟一个失败的情况
  return new MyPromise((resolve, reject) => {
    setTimeout(() => {
      reject(res + "2222222222");
    }, 1000);
  });
})
  .then((res2) => console.log("res2", res2)) // 这里不会被执行
  .catch((e) => console.error("e", e)) // 捕获到错误并处理
  .finally(() => {
    console.log("finally"); // 无论结果如何都会执行
  });

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值