手动实现Promise

// 定义异步调用的主类,名为 MyPromise
class MyPromise {
  // 执行器接收 resolve 和 reject 方法来改变 promise 的状态
  constructor(executor) {
    // 初始化状态为 "pending"
    this.state = "pending";
    // 初始化值为 undefined
    this.value = undefined;
    // 初始化原因为 undefined
    this.reason = undefined;
    // 完成状态回调函数集
    this.onResolvedCallbacks = [];
    // 拒绝状态回调函数集
    this.onRejectedCallbacks = [];

    // 在resolve中为value赋值
    const resolve = (value) => {
      //当状态为pending时进行状态更改和赋值操作
      if (this.state === "pending") {
        this.state = "fulfilled";
        this.value = value;
        // 当promise从pending状态转为fulfilled,会执行onResolvedCallbacks中的所有回调函数
        this.onResolvedCallbacks.forEach((fn) => fn());
      }
    };

    // 在reject中为reason赋值
    const reject = (reason) => {
      // 当状态为 pending 时进行状态更改和赋值操作
      if (this.state === "pending") {
        this.state = "rejected";
        this.reason = reason;
        // 当promise从pending状态转为rejected,会执行onRejectedCallbacks中的所有回调函数
        this.onRejectedCallbacks.forEach((fn) => fn());
      }
    };

    // 立即执行executor,错误则执行reject
    try {
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }

  // promise 有一个名为 then 的方法,它接受两个参数:onFulfilled 和 onRejected,然后返回一个新的 promise
  then(onFulfilled, onRejected) {
    // 对处理函数进行判定,如果其为空或者其不是函数,则赋值为默认函数
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };

    // 返回新的promise对象
    const promise2 = new MyPromise((resolve, reject) => {
      if (this.state === "fulfilled") {
        setTimeout(() => {
          try {
            const x = onFulfilled(this.value);
            this.resolvePromise(promise2, x, resolve, reject);
          } catch (err) {
            reject(err);
          }
        }, 0);
      }

      if (this.state === "rejected") {
        setTimeout(() => {
          try {
            const x = onRejected(this.reason);
            this.resolvePromise(promise2, x, resolve, reject);
          } catch (err) {
            reject(err);
          }
        }, 0);
      }
      // 当state为pending时,将onFulfilled和onRejected存放起来
      if (this.state === "pending") {
        this.onResolvedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onFulfilled(this.value);
              this.resolvePromise(promise2, x, resolve, reject);
            } catch (err) {
              reject(err);
            }
          }, 0);
        });

        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onRejected(this.reason);
              this.resolvePromise(promise2, x, resolve, reject);
            } catch (err) {
              reject(err);
            }
          }, 0);
        });
      }
    });

    return promise2;
  }

  // 对不同情况的x进行处理
  resolvePromise(promise2, x, resolve, reject) {
    // promise 和 x 引用同一对象,错误处理
    if (promise2 === x) {
      return reject(new TypeError("Chaining cycle detected for promise"));
    }

    let called = false;

    if (x instanceof MyPromise) {
      x.then(
        (value) => {
          if (called) return;
          called = true;
          this.resolvePromise(promise2, value, resolve, reject);
        },
        (reason) => {
          if (called) return;
          called = true;
          reject(reason);
        }
      );
    } else {
      resolve(x);
    }
  }

  // 返回一个完成状态的promise
  static resolve(value) {
    return new MyPromise((resolve, reject) => {
      resolve(value);
    });
  }

  // 返回一个拒绝状态的promise
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }

  // 返回一个 Promise 实例,该实例在 iterable 参数内所有的 promise 都“完成(Fulfilled)”或参数中不包含 promise 时回调完成(resolve)
  static all(promises) {
    return new MyPromise((resolve, reject) => {
      const result = [];
      let count = 0;

      const processResult = (index, value) => {
        result[index] = value;
        count++;
        // 所有结果都得到了则更新状态为fulfilled
        if (count === promises.length) {
          resolve(result);
        }
      };
      // 使用 forEach,能遍历到不是promise的其他类型
      promises.forEach((promise, index) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (value) => processResult(index, value),
            (reason) => reject(reason)
          );
        } else {
          processResult(index, promise);
        }
      });
    });
  }

  // 返回一个 Promise 实例,只有当 iterable 参数内的某个 promise 成功或失败时,返回的 promise 才会异步地 success 或 failure
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      promises.forEach((promise) => {
        if (promise instanceof MyPromise) {
          promise.then(resolve, reject);
        } else {
          resolve(promise);
        }
      });
    });
  }
}

调用举例

// 创建一个 Promise 对象
const promise = new MyPromise((resolve, reject) => {
  // 异步操作,比如网络请求或者定时器
  setTimeout(() => {
    // 异步操作成功,调用 resolve 并传递结果
    resolve('成功');
    // 或者异步操作失败,调用 reject 并传递错误原因
    // reject('失败');
  }, 1000);
});

// 使用 then 方法添加成功和失败的回调函数
promise.then(
  value => {
    console.log('成功的结果:', value);
  },
  reason => {
    console.log('失败的原因:', reason);
  }
);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值