手写一个promise

102 阅读1分钟

promise是前端常用api,也是面试常考题,所以直接手写一个promise可以深入理解此api,直接上代码

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class MyPromise {
  #state = PENDING;
  #result = undefined;
  #thenables = [];
  constructor(executor) {
    const resolve = (data) => {
      this.#changeState(FULFILLED, data);
    };
    const reject = (err) => {
      this.#changeState(REJECTED, err);
    };

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

  #changeState(state, result) {
    console.log('executor>>>', result);
    if (this.#state !== PENDING) return;
    this.#state = state;
    this.#result = result;
    // 队列执行
    this.#run();
  }

  #handleCallback(callback, resolve, reject) {
    if (typeof callback !== 'function') {
      // 状态不是函数
      queueMicrotask(() => {
        const settled = this.#state === FULFILLED ? resolve : reject;
        settled(this.#result);
      });
      return;
    }

    queueMicrotask(() => {
      try {
        const result = callback(this.#result);

        if (result instanceof MyPromise) {
          result.then(
            (value) => resolve(value),
            (err) => reject(err)
          );
        }

        resolve(result);
      } catch (err) {
        reject(err);
      }
    });
  }

  #run() {
    if (this.#state === PENDING) return;
    while (this.#thenables.length) {
      const { onFulfilled, onRejected, resolve, reject } =
        this.#thenables.shift();
      if (this.#state === FULFILLED) {
        this.#handleCallback(onFulfilled, resolve, reject);
      } else {
        this.#handleCallback(onRejected, resolve, reject);
      }
    }
  }

  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      this.#thenables.push({
        onFulfilled,
        onRejected,
        resolve,
        reject,
      });
      // 启动队列执行
      this.#run();
    });
  }
}