Promise手撕

88 阅读1分钟

Promise手撕

class myPromise{
  constructor(fn){
    if (typeof fn !== 'function') {
      throw new Error('MyPromise must accept a function as a parameter')
    }
    this.status = 'pending';
    this.value = undefined;
    this.resolveCalls = [];
    this.rejectCalls = [];
    try {
      fn(this.resolve,this.reject);
    }catch (err){
      this.reject(err);
    }
  }

  resolve = (val)=>{
    if (this.status === 'pending'){
      this.status = 'Fulfilled';
      this.value = val;
      this.resolveCalls.forEach((i)=>i(this.value));
    }
  }

  reject = (err)=>{
    if (this.status === 'pending'){
      this.status = 'Rejected';
      this.value = err;
      this.rejectCalls.forEach((i)=>i(this.value));
    }
  }

  then(FulfilledCall,RejectCall){
    //没有实现A+的链式调用,then需要返回新的promise并传递上一层then结果
    if (this.status === 'pending'){
      this.resolveCalls.push(FulfilledCall);
      this.rejectCalls.push(RejectCall);
    }else if (this.status === 'Fulfilled'){
      FulfilledCall(this.value);
    }else if (this.status === 'Rejected'){
      RejectCall(this.value);
    }
  }
}

all

Promise.all = function (arr){
  return new Promise((resolve,reject) => {
    let len = arr.length;
    let res = [];
    let nowResolved = 0;
    arr.forEach((i,index)=>{
      i.then((e)=>{
          res[index] = e;
          if (++nowResolved === len) resolve(res)
      })
        .catch(err=>{
            reject(err);
        })
    })
  })
}