Promise then异步及多次调用(四)

43 阅读1分钟
  1. 可能是异步的,隔了一段时间才改变promise的状态
  2. 一个promise的实例p,可能会有多个then。 eg: p.then... p.then... p.then...,每个then都要能收到状态变化后的回调
    const PENDING = "pending";
    const FULFILLED = "fulfilled";
    const REJECTED = "rejected";
    class FXPromise {
      state = PENDING;
      result = undefined;
      // 1. 定义回调数组,使用私有变量【不知道私有变量的自行查阅mozilla文档】
      #handlers = []; // [{onFulfilled,onRejected},... n个]  p.then  p.then  ... 一个实例可以同时then,每个都要有对应的回调

      constructor(fn) {
        const resolveFunc = (res) => {
          if (this.state === PENDING) {
            this.result = res;
            this.state = FULFILLED;
            // 3. 如果是异步的,状态改变的时候执行回调函数
            this.#handlers.forEach(({ onFulfilled }) =>
              onFulfilled(this.result)
            );
          }
        };
        const rejectFunc = (res) => {
          if (this.state === PENDING) {
            this.result = res;
            this.state = REJECTED;
            // 3. 如果是异步的,状态改变的时候执行回调函数
            this.#handlers.forEach(({ onRejected }) => onRejected(this.result));
          }
        };
        fn(resolveFunc, rejectFunc);
      }

      then(onFulfilled, onRejected) {
        onFulfilled =
          typeof onFulfilled === "function" ? onFulfilled : (x) => x;
        onRejected =
          typeof onRejected === "function"
            ? onRejected
            : (x) => {
                throw x;
              };
        if (this.state === FULFILLED) {
          onFulfilled(this.result);
        } else if (this.state === REJECTED) {
          onRejected(this.result);
        } else if (this.state === PENDING) {
          // 2. 保存回调函数
          this.#handlers.push({ onFulfilled, onRejected });
        }
      }
    }

    const p = new FXPromise((resolve, reject) => {
      setTimeout(() => {
        reject("err");
        resolve(111);
      }, 1000);
    });
    p.then(
      (res) => {
        console.log("then res ", res);
      },
      (err) => {
        console.log("then err ", err);
      }
    );
    p.then(
      (res) => {
        console.log("then2 res ", res);
      },
      (err) => {
        console.log("then2 err ", err);
      }
    );

image.png