手写一个MyPromise构造函数


参考网上资料,自己整理了一下思路

首先是一个最简化的MyPromise构造函数,参数是executor执行器函数。

接下来是,给这个构造函数增加then方法和catch方法。

 打印结果是

 最后一步是使构造函数可以链式调用。

function MyPromise(excutor) {
  console.log('进入MyPromise构造器');
  const _PENDING = 'pending';
  const _RESOLVED = 'resolved';
  const _REJECTED = 'rejected';

  const self = this; // 定义一个this指向, 避免在当前作用域下的this混乱
  self.PromiseStatus = _PENDING;
  self.PromiseValue = undefined;

  self.fullFilledList = []; // 用来存储Promise.then成功的回调函数
  self.rejectedList = []; // 用来存储Promise.then和Promise.catch失败的回调函数

  // success
  const resolve = data => {
    console.log('用户调用resolve方法,状态被推向resolved状态,并且将用户传递进来的数据赋值给PromiseValue');
    if (self.PromiseStatus === _PENDING) {
      self.PromiseStatus = _RESOLVED;
      self.PromiseValue = data;

      self.fullFilledList.forEach(item => {
        console.log('一旦用户状态被推向resolved状态则调用fullFilledList里面存储的成功的回调函数');
        item();
      });
    }
  }
  // error
  const reject = error => {
    console.log('用户调用reject方法,状态被推向rejected状态,并且将用户传递进来的数据赋值给PromiseValue');
    if (self.PromiseStatus === _PENDING) {
      self.PromiseStatus = _REJECTED;
      self.PromiseValue = error;

      self.rejectedList.forEach(item => {
        console.log('一旦用户状态被推向rejected状态则调用rejectedList里面存储的失败的回调函数');
        item();
      });
    }
  }
  try {
    console.log('到达立即执行器');
    excutor(resolve,reject);
  } catch(error) {
    reject(error);
  }

  MyPromise.prototype.then = (thenable, catchable) => {
    console.log('进入then函数');
    // 如果当前状态已经为已决阶段的两种状态了, 那么回调函数会被立即调用并执行
    // 因为catchable很有可能不传递, 所以必须容错
    catchable = typeof catchable === 'function' ? catchable : err => { throw err };
    if (self.PromiseStatus === _RESOLVED) {
      // console.log('MyPromise实例是resolved状态, 调用成功回调函数thenable-then,并返回PromiseValue');
      // thenable(self.PromiseValue)
      console.log('MyPromise实例是resolved状态,为了链式调用需要return出一个新的MyPromise实例');
      return new MyPromise((resolve, reject) => {
        try {
          const x = thenable(self.PromiseValue); // thenable回调函数return出的内容
          if (x instanceof MyPromise) {
            x.then(resolve, reject) // ??? 以后补充
          } else {
            resolve(x) // 将初始的pending状态推向resolved状态
          }
        } catch (err) {
          reject(err)
        }
      })
    } 
    if (self.PromiseStatus === _REJECTED) {
      // console.log('MyPromise实例是rejected状态, 调用失败回调函数catchable-then,并返回PromiseValue');
      // catchable(self.PromiseValue)
      console.log('MyPromise实例是rejected状态,为了链式调用需要return出一个新的MyPromise实例');
      return new MyPromise((resolve, reject) => {    
        try {
          console.log('调用失败回调函数catchable-then,并返回PromiseValue');
          const x = catchable(self.PromiseValue)
          if (x instanceof MyPromise) {
            x.then(resolve, reject)
          } else {
            resolve(x)
          }
        } catch (err) {
          reject(err)
        }
      })
    }
    if (self.PromiseStatus === _PENDING) {
      console.log('MyPromise实例是pending状态');
      return new MyPromise((resolve, reject) => {
        self.fullFilledList.push(() => {
          const x = thenable(self.PromiseValue)
          if (x instanceof MyPromise) {
            x.then(resolve, reject)
          } else {
            resolve(x)
          }
        })
        self.rejectedList.push(() => {
          try {
            const x = catchable(self.PromiseValue)
            if (x instanceof Promise) {
              x.then(resolve, reject)
            } else {
              resolve(x)
            }
          } catch (err) {
            reject(err)
          }
        })
      })
    }
  }
  MyPromise.prototype.catch = catchable => {
    console.log('进入catch函数');
    // if (self.PromiseStatus === _REJECTED) {
    //   console.log('MyPromise实例是rejected状态, 调用失败回调函数catchable-catch');
    //   catchable(self.PromiseValue)
    // }
    return self.then(null, catchable);
  }
};
const myPromise = new MyPromise((resolve, reject) => {
  // 立即执行且顺序执行
  console.log('我会立即执行');
  reject('hello');
})

const myPromise1 = myPromise.then(res => {
  console.log(res, 'thenable执行-then');
}, err => {
  console.log(err, 'catchable执行-then');
  return err;
})
myPromise1.then(res => {
  console.log(res, '第二个then');
  return res + ' world';
}).then(res => {
  console.log(res, '第三个then');
})
// const myPromise2 = myPromise.catch(err => {
//   console.log(err, 'catchable执行-catch');
// })

后续再完善。