JS系列-实现promise以及对应方法

在实现之前需要先理解Promise工作的机制,其实Promise就是一个构造函数,内部有三个状态,分别如下所示:

  1. pending
  2. resolved
  3. rejected

而要想将某个promise实例从初始的pending状态改变为resolved或者rejected状态则必须要通过resolve()或者reject()这两个方法,而需要注意的是promise实例的状态改变是不可逆的,因此在改变为resolved或者rejected之后后续的改变状态的操作会因此而无效

在Promsie原型对象中含有then、catch、all、race、finally这些方法
在本文章中就先实现promise构造函数以及then还有catch这两个方法

then这个方法可以接受两个参数,一个成功的回调,一个失败的回调。也就是onResolved和onRejected

catch这个方法只可以接受一个参数,失败的回调,也就是onRejected
并且then这个方法,是返回一个新的promise对象,它里面的执行方法也是异步的
触发then的时候,也会有三个可能,一个是状态为resolved时,一个是状态为rejected时,一个是状态为pending时
Promise的结果根据执行的结果返回

首先是promise构造函数的实现,具体实现如下:

function MyPromise(exec) {
      this.state = PENDING;
      this.value = null;
      this.reason = null;
      this.onFulfilledCallbacks = [];
      this.onRejectedCallbacks = [];

      const resolve = (value) => {
        if (this.state === PENDING) {
          this.state = FULFILLED;
          this.value = value;
          this.onFulfilledCallbacks.forEach(fun => {
            fun();
          });
        }
      }

      const reject = (reason) => {
        if (this.state === PENDING) {
          this.state = REJECTED;
          this.reason = reason;
          this.onRejectedCallbacks.forEach(fun => {
            fun();
          });
        }
      }

      try {
        exec(resolve, reject);
      } catch (reason) {
        reject(reason);
      }
    }

其次是promise的then方法实现,由于then方法可以链式调用,因此需要返回一个新的promise实例,具体实现如下:

  MyPromise.prototype.then = function (onFulfilled, onRejected) {
      if (typeof onFulfilled != 'function') {
        onFulfilled = function (value) {
          return value;
        }
      }
      if (typeof onRejected != 'function') {
        onRejected = function (reason) {
          throw reason;
        }
      }
      const promise2 = new MyPromise((resolve, reject) => {
        switch (this.state) {
          case FULFILLED:
            setTimeout(() => {
              try {
                const x = onFulfilled(this.value);
                resolve(x);
              } catch (reason) {
                reject(reason);
              }
            }, 0);
            break;
          case REJECTED:
            setTimeout(() => {
              try {
                const x = onRejected(this.reason);
                resolve(x);
              } catch (reason) {
                reject(reason);
              }
            }, 0);
            break;
          case PENDING:
            this.onFulfilledCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const x = onFulfilled(this.value);
                  resolve(x);
                } catch (reason) {
                  reject(reason);
                }
              }, 0);
            })
            this.onRejectedCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const x = onRejected(this.reason);
                  resolve(x);
                } catch (reason) {
                  reject(reason);
                }
              }, 0);
            })
            break;
        }
      })
      return promise2;
    }

最后是promise的catch方法实现,由于catch方法用于捕捉错误,因此只需要调用then方法返回一个新的promise实例即可,具体实现如下:

MyPromise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected);
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值