手写Promise

167 阅读1分钟

最近两天一直因为Promise的源码实现困扰,在网上查询了各种资料,写的标准也是五花八门,最后也查看了源码,最后总结,写出了此篇文章

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

class MyPromise {
  constructor(executor) {
    try {
      executor(this.resolve, this.reject);
    } catch (error) {
      this.reject(error);
    }
  }

  // 设置初始状态
  statue = PENDING;
  value = null;
  reason = null;
  // 存储成功和失败的回调
  onFulFilledCallback = [];
  onRejectedCallback = [];

  resolve = (value) => {
    if (this.statue === PENDING) {
      this.statue = FULFILLED;
      this.value = value;

      // 如果存在回调函数,就调用
      while (this.onFulFilledCallback.length) {
        this.onFulFilledCallback.shift()(value);
      }
    }
  };
  reject = (reason) => {
    if (this.statue === PENDING) {
      this.statue = REJECTED;
      this.reason = reason;

      // 如果存在回调函数,就调用
      while (this.onRejectedCallback.length) {
        this.onRejectedCallback.shift()(reason);
      }
    }
  };

  then(onFulfilled, onRejected) {
    onFulfilled =
      typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === 'function'
        ? onRejected
        : (reason) => {
            throw reason;
          };

    const promise2 = new MyPromise((resolve, reject) => {
      if (this.statue === FULFILLED) {
        queueMicrotask(() => {
          try {
            // 获取成功回调函数的执行结果
            const x = onFulfilled(this.value);
            // 传入 resolvePromise 集中处理
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.statue == REJECTED) {
        onRejected(this.reason);
      } else if (this.statue === PENDING) {
        this.onFulFilledCallback.push(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
        this.onRejectedCallback.push(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      }
    });

    return promise2;
  }

  // resolve静态方法
  static resolve(parameter) {
    // 如果传入MyPromise 直接返回
    if (parameter instanceof MyPromise) {
      return parameter;
    }

    // 转成常规方式
    return new MyPromise((resolve) => {
      resolve(parameter);
    });
  }

  // reject静态方法
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }
}

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    );
  }
  if (x instanceof MyPromise) {
    x.then(resolve, reject);
  } else {
    resolve(x);
  }
}

module.exports = MyPromise;

const MyPromise = require('./MyPromise');
// 测试用例

// MyPromise.resolve()
//   .then(() => {
//     console.log(0);
//     return MyPromise.resolve(4);
//   })
//   .then((res) => {
//     console.log(res);
//   });

// const promise = new MyPromise((resolve, reject) => {
//   setTimeout(() => {
//     resolve('success');
//   });
// });

// promise.then((value) => {
//   console.log('resolve', value);
// });

// // 这个时候将promise定义一个p1,然后返回的时候返回p1这个promise
// const p1 = promise.then((value) => {
//   console.log(1);
//   console.log('resolve', value);
//   return p1;
// });

// // 运行的时候会走reject
// p1.then(
//   (value) => {
//     console.log(2);
//     console.log('resolve', value);
//   },
//   (reason) => {
//     console.log(3);
//     console.log(reason.message);
//   }
// );

本文参考:juejin.cn/post/694531…