天天看點

前端面試之手撕代碼實作promise和其then、all、race、filnally方法

function _promise(resolver){
  this.status='pending';
  this.result='';
  resolver(this.resolve.bind(this),this.reject.bind(this));
}

function _promise.prototype.resolve(){
  if(this._status==='pending'){
    this._status='fulfilled';
    this.result=result;
  }
}

function _promise.prototype.reject(){
  if(this._status==='pending'){
    this._status='rejected';
    this.result=result;
  }
}

function _promise.prototype.then(){
  if(this._status==='fulfilled'){
    var _isPromise=isResolve(this,_result);
    if(_isPromise instanceof Promise){
      return _isPromise;
    }
    return this;
  }else if(this._status==='rejected'&&arguments[1]){
    var err=new TypeError(this.result);
    var _isPromise=isRejected(this,result);
    if(_isPromise instanceof Promise){
      return _isPromise;
    }
    return this;
  }
}

function _promise.prototype.all(promises){
  if (! Array.isArray(promises)){
    throw new TypeError('promises必須是個數組')
  }else{
    return new Promise(function(resolve,reject){
      var count=promises.length;
      var result=[];
      function resolver(value){
        resolveAll(value);
      }
      function rejecter(reason){
        reject(reason);
      }
      function resolveAll(value){
        result.push(value);
        if(--count===0){
          resolve(result);
        }
      }
      for(var i=0;i<promises.length;i++){
        promises[i].then(resolver,rejecter);
      }
    })
  }
}
function _promise.prototype.race(promises){
  var result=[];
  var count=promises.length;
  if(!Array.isArray(promises){
    throw new TypeError('promises需要是數組')
  })
  return new Promise((resolve,reject)=>{
    function resolver(value){
      resolve(value);
    }
    function rejecter(reason){
      reject(reason);
    }
    for(let i=0;i<promises.length;i++){
      promises[i].then(resolver,rejecter);
    }
  })
}

function _promise.prototype.finally(onFinally){
  return this.then(
    res=>Promise.resolve(onFinally()).then(()=>res),
    err=>Promise.resolve(onFinally()).then(()=>{throw err;})
  )
}
           

繼續閱讀