Promise的簡單實現(xiàn)

MyPromise的簡單偽實現(xiàn)

Promise對象表示一個異步操作的最終結(jié)果看政,用來傳遞異步傳輸?shù)臄?shù)據(jù)切省。實現(xiàn)Promise之前我們需要先了解一下Promise/A+規(guī)范

規(guī)范主要有以下幾點:

  1. Promise有三種狀態(tài)沦泌,pending溉痢、已完成fulfilled塘揣、rejected
  2. Promise的狀態(tài)只能從pending轉(zhuǎn)到fullfilled或者從pending轉(zhuǎn)向rejected蜡塌,不能逆向轉(zhuǎn)換,同時fullfilled和rejected之間也不能相互轉(zhuǎn)換
  3. Promise必須有一個then方法勿负,而且要返回一個Promise馏艾,供then方法的鏈?zhǔn)秸{(diào)用,也就是可thenable的
  4. then接受倆個回調(diào)函數(shù)(resolve與reject),在相應(yīng)的狀態(tài)轉(zhuǎn)變時觸發(fā)奴愉,回調(diào)可返回Promise琅摩,等待此Promise被resolved后,繼續(xù)觸發(fā)then鏈?zhǔn)秸{(diào)用

知道這幾個重要的特點锭硼,我們就可以參考瀏覽器內(nèi)置的api來實現(xiàn)一個Promise了房资,本文使用ES6語法

  • 首先,我們來看看Promise是如何使用的檀头,以及常用的一些API
let P = new Promise()

let func1 = () => {
    console.log('func1')
    setTimeout(() => {
        P.resolve('1')
    }, 1000)
    return P
}

let func2 = result => {
    console.log('func2', result)
    setTimeout(() => {
        P.reject('2')
    }, 1000)
}

let func3 = result => {
    console.log('func3', result)
    setTimeout(() => {
        P.resolve('3')
    }, 1000)
}

let func4 = result => {
    console.log('func4', result)
    setTimeout(() => {
        P.resolve('4')
    }, 1000)
}

let func5 = result => {
    console.log('func5', result)
}

//調(diào)用
func1().then(func2, func3).then(func3).then(func4).catch(func5)

以上就是一個Promise的基本使用轰异,通過分析上面的使用方法,我們發(fā)現(xiàn)Promise對象擁有then和catch方法暑始,同時可以鏈?zhǔn)秸{(diào)用搭独,接下來我們參照上面的案列來實現(xiàn)自己的Promise---MyPromise

  • 第一步 我們創(chuàng)建一個MyPromise類,擁有then和catch方法廊镜,
calss MyPromise {
  constructor(){

  }
  then(){

  }
  catch(){

  }
}
  • 第二步 添加狀態(tài)管理牙肝,因為有fullfiled和rejected兩種狀態(tài),那么我們就添加resolve方法和reject方法進行狀態(tài)管理
calss MyPromise {
  constructor(){

  }
  then(){

  }
  catch(){

  }
  // fullfiled狀態(tài)的管理
  resolve() {

  }

  // rejected狀態(tài)的管理
  reject() {

  }
}
  • 第三步 注冊回調(diào)函數(shù)與執(zhí)行回調(diào),設(shè)定一個數(shù)組對需要執(zhí)行的方法進行暫存配椭,以及一個方法的執(zhí)行器虫溜,該執(zhí)行器依賴于resolve和reject傳入的狀態(tài)進行相應(yīng)的執(zhí)行
calss MyPromise {
  constructor(){
    this.callbacks = [] //回調(diào)函數(shù)的儲存容器
  }
  then(){

  }
  catch(){

  }

  resolve() {    // fullfilled的管理

  }

  reject() {      // rejected的管理

  }

  execute(){    //回調(diào)函數(shù)觸發(fā)方法

  }
}
  • 第四步 編寫then函數(shù)與執(zhí)行器中的邏輯
    在寫then函數(shù)之前,先看看最開始Promise的調(diào)用方式 func1().then(func2,func3).then(func4).catch(fuc5)股缸,then方法接收兩個參數(shù)衡楞,一個成功回調(diào)一個失敗回調(diào),同時可以進行鏈?zhǔn)秸{(diào)用
then(onSuccess, onFail) {
  this.callbacks.push({
    resolve: onSuccess,
    reject: onFail
  })
  return this   //鏈?zhǔn)秸{(diào)用
}

這時候在調(diào)用func1時他會先返回Promise對象敦姻,然后再調(diào)用setTimeout里面的resolve回調(diào)并傳入?yún)?shù)瘾境,而在resolve函數(shù)中調(diào)用了執(zhí)行器execute,并且傳入了resolve這個狀態(tài)和在func1中傳入的參數(shù)替劈;

// fullfilled的管理
resolve(result) {
  this.execute('resolve', result)
}

// rejected的管理
reject(result) {
  this.execute('reject', result)
}

// 執(zhí)行execute函數(shù)寄雀,其實分析到了這一步就很簡單了得滤,不過是將先前傳入callbaks中的函數(shù)取出來陨献,然后執(zhí)行其中的成功回調(diào)就是了

execute(status, result) {
    // 取出之前傳入的回調(diào)函數(shù)對象(包含成功和失敗回調(diào)),然后執(zhí)行
    let handlerObj = this.callbacks.shift()
    handlerObj[type](result)
}

整體代碼

class MyPromise {
    constructor() {
        this.callbacks = []
    }

   then(onSuccess, onFail) {
     this.callbacks.push({
       resolve: onSuccess,
       reject: onFail
     })
     return this    //鏈?zhǔn)秸{(diào)用
   }

    catch (fail) {

        return this
    }

    resolve(result) {
        this.actuator('resolve', result)   // fullfilled的管理
    }

    reject(result) {
        this.actuator('reject', result)    // rejected的管理
    }

    // 執(zhí)行器
    execute(status, result) {
        // 取出之前傳入的回調(diào)函數(shù)懂更,執(zhí)行
        let handlerObj = this.callbacks.shift()
        handlerObj[status](result)
    }
}
  • 其實到了這一步眨业,Promise的基本功能then(以及回調(diào)resolve和reject)已經(jīng)實現(xiàn)了,接下來我們來實現(xiàn)catch方法沮协,catch方法就是在Promise變成rejected狀態(tài)的時候龄捡,調(diào)用執(zhí)行的回調(diào)
class MyPromise {
   constructor() {
       this.callbacks = [] //then的回調(diào)
       this.catchcallback = null //catach的回調(diào)
   }
 
     //此處省略其他代碼...............
   
   catch (onFail) {
       this.catchcallback = onFail // 保存?zhèn)魅氲氖』卣{(diào)
       return this // 用于鏈?zhǔn)秸{(diào)用
   }
 
 
     //此處省略其他代碼..............
 
 
   // 執(zhí)行器
   execute(status, result) {
       if (status === 'reject' && this.catchcallback) {
           this.callbacks = [] //catch方法的處理
           this.catchcallback(result)
       } else if (this.callbacks[0]) {
           // 取出之前傳入的回調(diào)函數(shù)對象(包含成功和失敗回調(diào)),然后執(zhí)行
           let handlerObj = this.callbacks.shift()
           handlerObj[status](result)
       }
   }
}  

下面來看看func1().then(func2, func3).then(func3).then(func4).catch(func5)的執(zhí)行結(jié)果吧

  1. 全部fullfilled狀態(tài)
  1. fun2為rejected狀態(tài)

至此慷暂,一個Promise的簡單偽實現(xiàn)就完成了聘殖,行文大概理清了promise的工作原理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末行瑞,一起剝皮案震驚了整個濱河市奸腺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌血久,老刑警劉巖突照,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異氧吐,居然都是意外死亡讹蘑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門筑舅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來座慰,“玉大人,你說我怎么就攤上這事翠拣〗侵瑁” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長邦尊。 經(jīng)常有香客問我背桐,道長,這世上最難降的妖魔是什么蝉揍? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任链峭,我火速辦了婚禮,結(jié)果婚禮上又沾,老公的妹妹穿的比我還像新娘弊仪。我一直安慰自己,他們只是感情好杖刷,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布励饵。 她就那樣靜靜地躺著,像睡著了一般滑燃。 火紅的嫁衣襯著肌膚如雪役听。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天表窘,我揣著相機與錄音典予,去河邊找鬼。 笑死乐严,一個胖子當(dāng)著我的面吹牛瘤袖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昂验,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼捂敌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了既琴?” 一聲冷哼從身側(cè)響起占婉,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呛梆,沒想到半個月后锐涯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡填物,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年纹腌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滞磺。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡升薯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出击困,到底是詐尸還是另有隱情涎劈,我是刑警寧澤广凸,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站蛛枚,受9級特大地震影響谅海,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹦浦,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一疚脐、第九天 我趴在偏房一處隱蔽的房頂上張望奠蹬。 院中可真熱鬧,春花似錦锌蓄、人聲如沸卧须。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豆拨。三九已至,卻和暖如春宇色,著一層夾襖步出監(jiān)牢的瞬間九杂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工代兵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留尼酿,地道東北人爷狈。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓植影,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涎永。 傳聞我的和親對象是個殘疾皇子思币,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 本文適用的讀者 本文寫給有一定Promise使用經(jīng)驗的人,如果你還沒有使用過Promise羡微,這篇文章可能不適合你谷饿,...
    HZ充電大喵閱讀 7,299評論 6 19
  • 00博投、前言Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大盯蝴。它由社區(qū)...
    夜幕小草閱讀 2,128評論 0 12
  • Promiese 簡單說就是一個容器毅哗,里面保存著某個未來才會結(jié)束的事件(通常是一個異步操作)的結(jié)果,語法上說捧挺,Pr...
    雨飛飛雨閱讀 3,352評論 0 19
  • Promise的含義: ??Promise是異步編程的一種解決方案虑绵,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和...
    呼呼哥閱讀 2,167評論 0 16
  • 改掉拖延癥,做事的節(jié)奏加快闽烙,每天定計劃翅睛,必須完成,對自己狠下心來。
    DC茜閱讀 217評論 0 1