如何實(shí)現(xiàn)精簡版的Promise(僅30行代碼)

網(wǎng)絡(luò)上面已經(jīng)有很多Promise的教程了。推薦一下這篇文章

知乎: 史上最易讀懂的 Promise/A+ 完全實(shí)現(xiàn)

但是本文的目的是為了使用最少量的代碼,以達(dá)到對(duì)Promise的實(shí)現(xiàn)有一個(gè)初步的了解。

下面是關(guān)于代碼實(shí)現(xiàn)的一些說明

  • 代碼中暫時(shí)不考慮任何異常情況
  • Promise對(duì)象只支持成功的回調(diào)
  • Promise支持鏈?zhǔn)秸{(diào)用
  • 本文僅實(shí)現(xiàn)兩種狀態(tài) 'pending' 和 'resolved'
第一步 定義Promise的內(nèi)部變量
self.status = 'pending';//初始狀態(tài)
self.onResolvedCallback = [];
self.data = undefined;
  • status: 保存當(dāng)前Promise的狀態(tài), 初始化時(shí)為 pending 狀態(tài)
  • onResolvedCallback: 當(dāng)Promise還處于pending狀態(tài)時(shí),將鏈?zhǔn)秸{(diào)用中的回調(diào)函數(shù)綁定到數(shù)組中
  • data: 保存當(dāng)前Promise的返回值
第二步 定義resolve函數(shù)
function resolve(data){
  if(self.status == 'pending'){
    self.status = 'resolved';
    self.data = data;
    self.onResolvedCallback.forEach(callback => callback(data));
  }
}

resolve 函數(shù)向外提供了修改當(dāng)前Promise狀態(tài)值的方法。并且保存Promise的結(jié)果。(如果在Promise 為 pending狀態(tài)時(shí),有鏈?zhǔn)交卣{(diào)。那么執(zhí)行這些回調(diào)函數(shù))

第三步 定義then方法
Promise.prototype.then = function(onResolved){
  var self = this;
  if(self.status == 'pending'){
    return new Promise(function(resolve){
      self.onResolvedCallback.push(function(value){
        var result = onResolved(value);
        resolve(result);
      });
    });
  }else{//本文只實(shí)現(xiàn)了'pending' 和 'resolved'兩種狀態(tài),所以沒判斷rejected相關(guān)代碼
    return new Promise(function(resolve){
      var result = onResolved(self.data);
      resolve(result);
    });
  }
}

then方法主要實(shí)現(xiàn)了兩步

  • 當(dāng)Promise處于pending狀態(tài),保存回調(diào)函數(shù)到onResolvedCallback中,返回新的Promise實(shí)例
  • 當(dāng)Promise不處于pending狀態(tài)時(shí),直接獲取上一步的返回值(self.data),調(diào)用回調(diào)函數(shù),返回新的Promise實(shí)例
以下為完整的代碼
function Promise(executor){
    var self = this;
    self.status = 'pending';
    self.onResolvedCallback = [];
    self.data = undefined;
    
    function resolve(data){
        if(self.status == 'pending'){
            self.status = 'resolved';
            self.data = data;
            self.onResolvedCallback.forEach(callback => callback(data));
        }
    }
    
    executor(resolve);//執(zhí)行回調(diào)函數(shù)
}

Promise.prototype.then = function(onResolved){
    var self = this;
    if(self.status == 'pending'){
        return new Promise(function(resolve){
            self.onResolvedCallback.push(function(value){
                var result = onResolved(value);
                resolve(result);
            });
        });
    }else{
        return new Promise(function(resolve){
            var result = onResolved(self.data);
            resolve(result);
        });
    }
}
以下為一個(gè)用例
new Promise(function(resolve){
    setTimeout(function(){
        resolve('123');
    }, 3000);
}).then(function(value){
    console.log('then 1', value);
    return value + 1;
}).then(function(value2){
    console.log('then 2', value);
    return value2;
})
//等待3秒后,頁面上輸出
//then 1: 123
//then 2: 1231
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 本文適用的讀者 本文寫給有一定Promise使用經(jīng)驗(yàn)的人,如果你還沒有使用過Promise,這篇文章可能不適合你,...
    HZ充電大喵閱讀 7,448評(píng)論 6 19
  • 目錄:Promise 的含義基本用法Promise.prototype.then()Promise.prototy...
    BluesCurry閱讀 1,559評(píng)論 0 8
  • Promiese 簡單說就是一個(gè)容器,里面保存著某個(gè)未來才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果,語法上說,Pr...
    雨飛飛雨閱讀 3,485評(píng)論 0 19
  • 00、前言Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)...
    夜幕小草閱讀 2,225評(píng)論 0 12
  • 今天又是勞動(dòng)的一天。 每年到這幾天,我就會(huì)特別想念離開我的親人,懷念媽媽帶我們勞動(dòng)的美好時(shí)刻。 記憶中,媽媽永遠(yuǎn)忙...
    琴素親子閱讀 350評(píng)論 0 1

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