手撸Promise 构造函数源码

首先,需要定义一个名为 MyPromise 的构造函数,它接受一个执行器函数作为参数;该执行器函数接收两个参数:resolve 和 reject,用于改变 Promise 状态的内部函数:

class MyPromise {
  constructor(executor) {
    this.state = 'pending'; // 初始化状态为pending
    this.value = undefined; // fulfilled时保存的值
    this.reason = undefined; // rejected时保存的原因
    this.onFulfilledCallbacks = []; // fulfilled时执行的回调队列
    this.onRejectedCallbacks = []; // rejected时执行的回调队列

    // 执行器函数会在new Promise时立即执行
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      // 如果执行器函数抛出错误,则直接将Promise变为rejected状态
      this.reject(error);
    }
  }

  resolve(value) {
    if (this.state === 'pending') {
      this.state = 'fulfilled';
      this.value = value;
      // 将pending状态下的成功回调全部执行
      this.onFulfilledCallbacks.forEach(cb => cb(this.value));
    }
  }

  reject(reason) {
    if (this.state === 'pending') {
      this.state = 'rejected';
      this.reason = reason;
      // 将pending状态下的失败回调全部执行
      this.onRejectedCallbacks.forEach(cb => cb(this.reason));
    }
  }

  // then方法用于注册成功和失败的回调
  then(onFulfilled, onRejected) {
    const self = this;
    let resolvedPromise;

    // 根据规范,onFulfilled/onRejected都是可选参数,并且需确保为函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val;
    onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err; };

    // 返回一个新的Promise以便进行链式调用
    resolvedPromise = new MyPromise((resolve, reject) => {
      if (self.state === 'pending') {
        // 如果当前Promise未决,则将回调存入相应的队列
        self.onFulfilledCallbacks.push(() => {
          try {
            const x = onFulfilled(self.value);
            resolvePromise(resolvedPromise, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
        self.onRejectedCallbacks.push(() => {
          try {
            const x = onRejected(self.reason);
            resolvePromise(resolvedPromise, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      } else if (self.state === 'fulfilled') {
        // 当前Promise已决议(resolved),则立即执行onFulfilled回调
        setTimeout(() => {
          try {
            const x = onFulfilled(self.value);
            resolvePromise(resolvedPromise, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else if (self.state === 'rejected') {
        // 当前Promise已拒绝(rejected),则立即执行onRejected回调
        setTimeout(() => {
          try {
            const x = onRejected(self.reason);
            resolvePromise(resolvedPromise, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }
    });

    return resolvedPromise;
  }

  // 这里省略了catch、finally等方法以及Promise.all、race等静态方法的实现
}

// 辅助函数,处理then中返回值的逻辑
function resolvePromise(promise2, x, resolve, reject) {
  // 规范要求对x进行递归解析,并处理循环引用等情况
  if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
  }

  let called; // 避免重复调用resolve或reject
  
  if (x instanceof MyPromise) {
    if (x.state === 'pending') {
      x.then(
        value => resolvePromise(promise2, value, resolve, reject),
        reason => reject(reason)
      );
    } else {
      x.then(resolve, reject);
    }
  } else if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
    try {
      let then = x.then;
      if (typeof then === 'function') {
        // 处理thenable对象
        then.call(
          x,
          y => {
            if (called) return;
            called = true;
            resolvePromise(promise2, y, resolve, reject);
          },
          r => {
            if (called) return;
            called = true;
            reject(r);
          }
        );
      } else {
        resolve(x);
      }
    } catch (error) {
      if (called) return;
      called = true;
      reject(error);
    }
  } else {
    resolve(x); // 基本类型的值直接resolve
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开机就来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值