class版本的手写Promise

40 阅读1分钟

上篇文章我们已经详细的把Promise的手写过程给讲解了,只不过用的是构造函数的方式,现在我们用class的方式来整理一遍,因为上篇文章已经很详细了,所以这次直接上代码。

class MyPromise {
  // 构造方法写在这里,new的时候直接执行
  constructor(executor) {
    this.PromiseState = "pending";
    this.PromiseResult = undefined;
    this.callbacks = [];
    const self = this;

    function resolve(data) {
      if (self.PromiseState !== "pending") return;
      self.PromiseState = "fulfilled";
      self.PromiseResult = data;

      setTimeout(() => {
        self.callbacks.forEach((item) => {
          item.onResolved && item.onResolved(data);
        });
      });
    }

    function reject(reason) {
      if (self.PromiseState !== "pending") return;
      self.PromiseState = "rejected";
      self.PromiseResult = reason;

      setTimeout(() => {
        self.callbacks.forEach((item) => {
          item.onRejected && item.onRejected(reason);
        });
      });
    }

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  // then方法在这里,给实例使用
  then(onResolved, onRejected) {
    const self = this;
    if (typeof onRejected !== "function") {
      onRejected = (reason) => {
        throw reason;
      };
    }
    if (typeof onResolved !== "function") {
      onResolved = (value) => value;
    }
    return new MyPromise((resolve, reject) => {
      function callback(type) {
        try {
          let result = type(self.PromiseResult);
          if (result instanceof MyPromise) {
            result.then(
              (v) => {
                resolve(v);
              },
              (r) => {
                reject(r);
              }
            );
          } else {
            resolve(result);
          }
        } catch (e) {
          reject(e);
        }
      }
      if (this.PromiseState === "fulfilled") {
        setTimeout(() => {
          callback(onResolved);
        });
      }
      if (this.PromiseState === "rejected") {
        setTimeout(() => {
          callback(onResolved);
        });
      }
      if (this.PromiseState === "pending") {
        this.callbacks.push({
          onResolved: function () {
            callback(onResolved);
          },
          onRejected: function () {
            callback(onRejected);
          },
        });
      }
    });
  }

  // catch也是一样
  catch(onRejected) {
    return this.then(undefined, onRejected);
  }

  // resolve方法不一样了,因为MyPromise的静态方法,前面加上static
  static resolve(value) {
    return new MyPromise((resolve, reject) => {
      if (value instanceof MyPromise) {
        value.then(
          (v) => {
            resolve(v);
          },
          (r) => {
            reject(r);
          }
        );
      } else {
        resolve(value);
      }
    });
  }

  // reject方法也一样
  static reject(value) {
    return new MyPromise((resolve, reject) => {
      reject(value);
    });
  }

  // all方法也一样
  static all(promises) {
    return new MyPromise((resolve, reject) => {
      let count = 0;
      let arr = [];
      for (let i = 0; i < promises.length; i++) {
        if (!(promises[i] instanceof MyPromise)) {
          promises[i] = MyPromise.resolve(promises[i]);
        }
        promises[i].then(
          (v) => {
            count++;
            arr[i] = v;
            if (count === promises.length) {
              resolve(arr);
            }
          },
          (r) => {
            reject(r);
          }
        );
      }
    });
  }

  // race方法也一样
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++) {
        if (!(promises[i] instanceof MyPromise)) {
          promises[i] = MyPromise.resolve(promises[i]);
        }
        promises[i].then(
          (v) => {
            resolve(v);
          },
          (r) => {
            reject(r);
          }
        );
      }
    });
  }
}