实现一个PromiseA+

简介

通过实现一个PromiseA+来加强对promise的理解,仅供参考~
讲解请看注释
在这里插入图片描述

// https://promisesaplus.com/
function onResolvedDefault() {}
function onRejectedDefault() {}
class PromiseA {
  status: 'pending' | 'resolved' | 'rejected'  = 'pending'// promise的状态
  value: any  = undefined// resolve的值
  reason: any = undefined // reject 的原因
  resolveCallbacks: Function[] = [] // 成功时的回调数组
  rejectCallbacks: Function[] = [] // 失败时的回调数组

  constructor(executor: Function) {
    executor(this.resolve.bind(this), this.reject.bind(this))
  }

  private resolve(value: any) {
    if(this.status === 'pending') {
      this.value = value
      this.status = 'resolved'
      this.resolveCallbacks.forEach(fn => {
        fn(this.value)
      })
    }
  }

  private reject(reason: any) {
    if(this.status === 'pending') {
      this.reason = reason
      this.status = 'rejected'
      this.rejectCallbacks.forEach(fn => {
        fn(this.reason)
      })
    }
  }

  then(onResolved?, onRejected?) {
    const that = this
    
    const _onResolved = typeof onResolved === 'function' ? onResolved : onResolvedDefault
    const _onRejected = typeof onResolved === 'function' ? onRejected : onRejectedDefault
    
    if (this.status === 'resolved') {
      // 2.2.6 then must return a promise
      return new PromiseA( /* 记作 resolvePromise*/
        // 这里不使用箭头函数时因为, 我们在调用resolvePromise需要this上面这个新生成的resolvePromise实例
        function(resolve, reject) {
          const res = _onResolved(that.value)
          // 2.2.7.1 [[Resolve]](resolvePromise, x)
          // 这个this指向这里新返回的 rejectPromise
          resolvePromise(this, res, resolve, reject)
        }
      )
    }
  
    if (this.status === 'rejected') {
      return new PromiseA(
        function(resolve, reject) {
          const res = _onRejected(that.reason)
          resolvePromise(this, res, resolve, reject)
        }
      )
    }
  
    if (this.status === 'pending') {
      return new PromiseA(function(resolve, reject) {
        that.resolveCallbacks.push(
          function(value) {
            const res = _onResolved(value)
            resolvePromise(this, res, resolve, reject)
          }
        )

        that.rejectCallbacks.push(
          function(reason) {
            const res = _onRejected(reason)
            resolvePromise(this, res, resolve, reject)
          }
        )
      })
    }
  }
}

// 这个函数只要结合 https://promisesaplus.com/ 网站上的
// 从 --To run [[Resolve]](promise, x), perform the following steps:-- 开始的解释逐句翻译过来就行了
function resolvePromise(promise: PromiseA, val: any, resolve, reject) {
  // val可能的值  普通值(直接可用) | PromiseA的实例 | thenable对象
  // 判断 x 是否为对象(排除null情况)或函数
  let called = false;
  if(promise === val) throw new TypeError() // 2.3.1
  // if(val instanceof PromiseA) {
  //   val.then(resolve, reject)
  // }
  if ((typeof val === "object" && val !== null) || typeof val === "function")  {
    if (typeof val.then === "function") {
      val.then.call(val,
        (value) => {
          // 添加锁,避免成功后执行失败
          if (called) return;
          called = true;
          resolvePromise(promise, value, resolve, reject);
        },
        (reason) => {
          // 添加锁,避免失败后执行成功
          if (called) return;
          called = true;
          reject(reason);
        }
      );
    } else {
      resolve(val);
    }
  } else {
    resolve(val)
  }
}
测试代码
const aa = new PromiseA((resolve, reject) => {
  resolve('1111')
}).then(val => {
  console.log(val)
  return new PromiseA((resolve) => {
    setTimeout(() => {
      resolve('222')
    }, 1000)
  })
})
aa.then(console.log)
/// 111
/// 222(一秒后) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值