ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

手写一个MyPromise构造函数

2021-12-01 12:03:45  阅读:106  来源: 互联网

标签:console log catchable self MyPromise reject 手写 构造函数


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

首先是一个最简化的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');
// })

后续再完善。

标签:console,log,catchable,self,MyPromise,reject,手写,构造函数
来源: https://www.cnblogs.com/front-end-wang/p/15628300.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有