手写符合Promise A+ 规范的Promise

1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行

2. executor 接受两个参数,分别是 resolve 和 reject

3. 了解Promise内部三个状态,并且知道其内部执行逻辑。状态一旦确认,就不会再改变, 只能从 pending--->rejected, 或 pending ---> fulfilled

5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled,和 promise 失败的回调 onRejected

6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。如果promise已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。如果promise的状态是pending,需要将onFulfilled和onRejected函数存放起来,等待状态确定后,再依次将对应的函数执行

7. then 的参数 onFulfilled 和 onRejected (可以省略)

8. promise 可以then多次,promise 的then 方法返回一个 promise

9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled)

10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected)

11.如果 then 返回的是一个promise,那么需要等这个promise,那么会等这个promise执行完,promise如果成功,就走下一个then的成功,如果失败,就走下一个then的失败

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
const isPromise = x => {
  return x !== null && (typeof x === 'object' || typeof x === 'function');
};

const resolvePromise = (callBack, x, resolve, reject) => {
  if (callBack === x) {
    reject(new TypeError('can not resolve promise self'));
  }
  let runCallBack = false;
  if (isPromise(x)) {
    try {
      const then = x.then;
      if (typeof then === 'function') {
        then.call(
          x,
          function (y) {
            if (runCallBack) return;
            runCallBack = true;
            resolvePromise(callBack, y, resolve, reject);
          },
          function (r) {
            if (runCallBack) return;
            runCallBack = true;
            reject(r);
          },
        );
      } else {
        resolve(x);
      }
    } catch (error) {
      if (runCallBack) return;
      runCallBack = true;
      reject(error);
    }
  } else {
    resolve(x);
  }
};
const runMicroTask = fn => {
  if (typeof process === 'object' && typeof process.nextTick === 'function') {
    process.nextTick(fn);
  } else if (typeof MutationObserver === 'function') {
    const ob = new MutationObserver(fn);
    const p = document.createElement('p');
    ob.observe(p, { childList: true });
    p.innerHTML = '1';
  } else {
    setTimeout(fn);
  }
};
class Promise {
  #state = PENDING;
  #result = undefined;
  #onFulfilledCallback = [];
  #onRejectedCallback = [];
  constructor(executor) {
    if (typeof executor !== 'function') {
      throw new TypeError(`${executor} is not a function`);
    }
    let resolve = value => {
      if (this.#state === PENDING) {
        this.#state = FULFILLED;
        this.#result = value;
        this.#onFulfilledCallback.forEach(fn => fn());
      }
    };
    let reject = reason => {
      if (this.#state === PENDING) {
        this.#state = REJECTED;
        this.#result = reason;
        this.#onRejectedCallback.forEach(fn => fn());
      }
    };
    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e);
    }
  }
  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value;
    }
    if (typeof onRejected !== 'function') {
      onRejected = reason => {
        throw reason;
      };
    }
    let resolve, reject;
    let promise = new Promise((res, rej) => {
      resolve = res;
      reject = rej;
    });
    let resolveFn = () => {
      runMicroTask(() => {
        try {
          let x = onFulfilled(this.#result);
          resolvePromise(promise, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      });
    };

    let rejectFn = () => {
      runMicroTask(() => {
        try {
          let x = onRejected(this.#result);
          resolvePromise(promise, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      });
    };
    if (this.#state === PENDING) {
      this.#onFulfilledCallback.push(resolveFn);
      this.#onRejectedCallback.push(rejectFn);
    } else if (this.#state === FULFILLED) {
      resolveFn();
    } else if (this.#state === REJECTED) {
      rejectFn();
    }
    return promise;
  }
}

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值