手写Promise

class MyPromise {
  constructor(executor) {
    // 初始状态为 pending
    this.status = "pending";
    // 存储 resolve 和 reject 的结果
    this.value = undefined;
    this.error = undefined;

    // 存储成功回调和失败回调
    this.onResolvedCallbacks = [];
    this.onRejectedCallbacks = [];

    // 执行执行器函数,传入 resolve 和 reject 函数
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (e) {
      this.reject(e);
    }
  }

  // resolve 方法将 Promise 状态改为 fulfilled,存储 resolve 后的值,并执行成功回调
  resolve(value) {
    if (this.status === "pending") {
      this.status = "fulfilled";
      this.value = value;
      this.onResolvedCallbacks.forEach((fn) => fn());
    }
  }

  // reject 方法将 Promise 状态改为 rejected,存储 reject 后的值,并执行失败回调
  reject(error) {
    if (this.status === "pending") {
      this.status = "rejected";
      this.error = error;
      this.onRejectedCallbacks.forEach((fn) => fn());
    }
  }

  // then 方法接收两个参数,成功回调和失败回调
  then(onResolved, onRejected) {
    // 创建一个新的 Promise 对象
    const promise2 = new MyPromise((resolve, reject) => {
      // 如果当前状态是 fulfilled,则执行成功回调,并将其返回值传递给下一个 Promise
      if (this.status === "fulfilled") {
        setTimeout(() => {
          try {
            const x = onResolved(this.value);
            this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
          } catch (e) {
            reject(e);
          }
        }, 0);
      }

      // 如果当前状态是 rejected,则执行失败回调,并将其返回值传递给下一个 Promise
      if (this.status === "rejected") {
        setTimeout(() => {
          try {
            const x = onRejected(this.error);
            this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
          } catch (e) {
            reject(e);
          }
        }, 0);
      }

      // 如果当前状态是 pending,则分别将成功回调和失败回调存储到数组中,等待状态改变后执行
      if (this.status === "pending") {
        this.onResolvedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onResolved(this.value);
              this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
            } catch (e) {
              reject(e);
            }
          }, 0);
        });

        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onRejected(this.error);
              this.resolvePromise(promise2, x, resolve, reject); // 解析链式 Promise
            } catch (e) {
              reject(e);
            }
          }, 0);
        });
      }
    });

    return promise2;
  }

  // 解析链式 Promise
  resolvePromise(promise2, x, resolve, reject) {
    // 如果 promise2 和 x 相等,则抛出 TypeError
    if (promise2 === x) {
      return reject(new TypeError("Chaining cycle detected for promise!"));
    }

    // 如果 x 是一个 Promise,则等待它的状态改变后再处理
    if (x instanceof MyPromise) {
      x.then(
        (value) => this.resolvePromise(promise2, value, resolve, reject),
        (error) => reject(error)
      );
    } else {
      // 如果 x 是一个普通值,则直接传递给下一个 Promise
      resolve(x);
    }
  }

  // catch 方法用来捕获 Promise 的错误
  catch(onRejected) {
    return this.then(null, onRejected);
  }

  // finally 方法用来在 Promise 执行结束后执行一些操作
  finally(callback) {
    return this.then(
      (value) => MyPromise.resolve(callback()).then(() => value),
      (error) =>
        MyPromise.resolve(callback()).then(() => {
          throw error;
        })
    );
  }

    // all 方法用来将多个 Promise 实例包装成一个新的 Promise 实例
  static all(promises) {
    return new MyPromise((resolve, reject) => {
      const results = [];
      let count = 0;

      for (let i = 0; i < promises.length; i++) {
        // 如果 promises[i] 不是一个 Promise,则将其视为已经 fulfilled 状态的 Promise
        if (!(promises[i] instanceof MyPromise)) {
          promises[i] = MyPromise.resolve(promises[i]);
        }

        // 监听每个 Promise 的状态变化,如果全部都变成 fulfilled,则将结果数组传递给下一个 Promise
        promises[i].then(
          (value) => {
            results[i] = value;
            count++;

            if (count === promises.length) {
              resolve(results);
            }
          },
          (error) => {
            reject(error);
          }
        );
      }
    });
  }

  // race 方法返回一个新的 Promise,它将由第一个完成的 Promise 的值或错误来决定自己的状态和值
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++) {
        // 如果 promises[i] 不是一个 Promise,则将其视为已经 fulfilled 状态的 Promise
        if (!(promises[i] instanceof MyPromise)) {
          promises[i] = MyPromise.resolve(promises[i]);
        }

        // 监听每个 Promise 的状态变化,如果有一个变成 fulfilled 或 rejected,则将其状态和值传递给下一个 Promise
        promises[i].then(
          (value) => {
            resolve(value);
          },
          (error) => {
            reject(error);
          }
        );
      }
    });
  }

  // resolve 方法返回一个新的 Promise,它的状态和值都是已知的
  static resolve(value) {
    return new MyPromise((resolve, reject) => {
      resolve(value);
    });
  }

  // reject 方法返回一个新的 Promise,它的状态和错误都是已知的
  static reject(error) {
    return new MyPromise((resolve, reject) => {
      reject(error);
    });
  }
}

// 测试代码
const p1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("p1");
  }, 1000);
});

const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject("p2");
  }, 500);
});

MyPromise.all([p1, p2])
  .then((results) => {
    console.log(results); // ["p1", undefined]
  })
  .catch((error) => {
    console.log(error); // "p2"
  });

MyPromise.race([p1, p2])
  .then((result) => {
    console.log(result); // "p1"
  })
  .catch((error) => {
    console.log(error); // "p2"
  });

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值