原生JS模擬Promise實現(xiàn)詳解

作為一名程序猿,經(jīng)常遇到回調(diào)函數(shù)的情況,原生js的回調(diào)函數(shù)是一層一層的嵌套調(diào)用,而es6提供了一種新的寫法,Promise,它可以把原本的嵌套回調(diào)函數(shù)實現(xiàn)成橫向的調(diào)用,即鏈式調(diào)用。
下面看一個Promise的簡單用法:

//Promise函數(shù)接受一個函數(shù)作為參數(shù),接受的函數(shù)中的resolve和reject分別作為執(zhí)行成功和執(zhí)行失敗的函數(shù)
var promise = new Promise(function(resolve, reject){
  if(/*異步執(zhí)行成功*/){
    resolve()
  }else{
    reject()  
  }
})
//通過then設(shè)置之后的兩個操作
.then(function(){
  //回調(diào)執(zhí)行成功的操作
},function(){
  //回調(diào)執(zhí)行失敗的操作
})

接著開始模擬:

(一)模擬模擬Promise構(gòu)造函數(shù)

function _Promise(resolver){
  this._status = 'pending'
  this._result = ''
  resolver(this.resolve.bind(this), this.reject.bind(this))
}

首先,_Promise構(gòu)造函數(shù)會接收一個函數(shù)resolver并執(zhí)行,函數(shù)中又包含resolve和reject兩個參數(shù),然后,_Promise構(gòu)造函數(shù)生成的實例有三種狀態(tài),分別是pending(初始值)、fullfilled(成功)和rejected(失?。矣蓀ending變?yōu)槌晒蛘呤『鬆顟B(tài)不可逆。

(二)實現(xiàn)resolve和reject函數(shù)

_Promise.prortotype.resolve = function(result){
  if(this._status === 'pending'){
    this._status = 'fullfilled'
    this._result = result
  }
}
_Promise.prototype.reject = function(result){
  if(this._status === 'pending'){
    this._status = 'rejected'
    this._result = result
  }
}

resolve和reject函數(shù)執(zhí)行的時候會先判斷狀態(tài),如果是pending則執(zhí)行,且將狀態(tài)變?yōu)閒ullfilled或者rejected,并將resolve/reject函數(shù)中參數(shù)傳遞給_result,以便then函數(shù)調(diào)用時使用。

(三)模擬then函數(shù)

_Promise.prototype.then = function(isResolve, isReject){
  if(this._status === 'fullfilled'){
    var _isPromise = isResolve(this._result)  //執(zhí)行成功函數(shù)
    if(_isPromise instanceof _Promise){  //如果執(zhí)行成功函數(shù)后返回的是_Promise實例,則返回這個實例
      return _Promise
    }
    return this
  }else if(this._status === 'rejected' && arguments[1]){  //只有狀態(tài)是失敗且有第二個參數(shù)才執(zhí)行
    var err = new TypeError(this._result)
    var _isPromise = isReject(err)  //將錯誤信息傳遞給失敗函數(shù)
    if(_isPromise instanceof _Promise){  //如果執(zhí)行失敗函數(shù)后返回的是_Promise實例,則返回這個實例
      return _Promise
    }
    return this
  } 
}

因為有可能存在鏈式調(diào)用,所以執(zhí)行then函數(shù)的返回值需要判斷,如果isResolve或者isReject函數(shù)返回的是一個新的_Promise實例,則返回這個實例,否則返回當前實例

(四)模擬catch函數(shù)

//catch函數(shù)與reject函數(shù)十分類似
_Promise.prototype.catch = function(isReject){
  if(this._status === 'rejected'){
    var _isPromise = isReject(this._result)  
    if(_isPromise instanceof _Promise){
      return _Promise
    }
    return this
  }
}

至此,Promise已經(jīng)模擬完成~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容