Promise原理解析厕鹃,使用ES5實(shí)現(xiàn)Promise

Promise

js的單線程特性導(dǎo)致大量的異步操作兢仰,異步操作我們通常使用函數(shù)回調(diào)的方式實(shí)現(xiàn)。大量的函數(shù)回調(diào)會產(chǎn)生我們的毀掉地獄剂碴,降低代碼的可讀性和可維護(hù)性把将。

為了解決這些問題,先后出現(xiàn)了Promise函數(shù)忆矛、Generator函數(shù)和async函數(shù)察蹲。目前Promise配合async/await成為了主流。

Promise本質(zhì)上并沒有改變異步操作催训,只是讓我們可以用同步的代碼寫法去書寫異步操作洽议。增加代碼的可讀性。

Promise是ES6中確定的漫拭,今天我們就使用ES5的寫法亚兄,手動實(shí)現(xiàn)自己的Promise,以求徹底掌握Promise的核心原理采驻。今天我們只封裝實(shí)現(xiàn)Promise的基本功能审胚。

先看一下在ES6中我們是如何使用Promise的

let promiseFn = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111)
  }, 1000)
});
promiseFn.then(res => {
  console.log(res) // res === 111
})

// 使用async/await
async function promiseFn () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(111)
    }, 1000)
  })         
}
 let res = await promiseFn() // res === 111

Promise規(guī)范

Promise規(guī)范的原文地址

Promise規(guī)范的中文翻譯地址

里面詳細(xì)介紹了Promise的各種術(shù)語、定義和規(guī)范挑宠。其中最需要理解的就是Promise的三種狀態(tài)以及其中的狀態(tài)變化⊥怯埃“等待態(tài)(Pending)各淀、執(zhí)行態(tài)(Fulfilled)和拒絕態(tài)(Rejected)”。

狀態(tài)改變不可逆诡挂,只能Pending --> Fulfilled 或者 Pending --> Rejected

WX20190620-174026@2x.png

預(yù)備

使用status存儲Promise狀態(tài)(pending碎浇、fulfilled临谱、rejected)
使用value存儲resolve的數(shù)據(jù)
使用err存儲reject的錯誤信息
使用原型鏈繼承的方式創(chuàng)建then函數(shù)
使用onFulfilledArr存儲將要執(zhí)行的resolve函數(shù)
使用onRejectedArr存儲將要執(zhí)行的reject函數(shù)

創(chuàng)建 MyPromise構(gòu)造函數(shù)

// 創(chuàng)建 MyPromise構(gòu)造函數(shù)
function MyPromise (fn) {
  let self = this;
  this.value = null; // 存儲resolve數(shù)據(jù)
  this.status = 'pending'; // 存儲狀態(tài)
  this.err = null; // 存儲reject錯誤信息
  this.onFulfilledArr = []; // 存儲將要執(zhí)行的resolve函數(shù)
  this.onRejectedArr = []; // 存儲將要執(zhí)行的reject函數(shù)
  function resolveFn (val) { // resolve()時執(zhí)行的函數(shù)
    if (self.status === 'pending') { // 只用pending狀態(tài)才能繼續(xù)進(jìn)行
      self.value = val; // 存儲數(shù)據(jù)
      self.status = 'fulfilled'; // 改變狀態(tài)
      // 逐個調(diào)用then()函數(shù)
      self.onFulfilledArr.forEach(function(thenFn) {
          thenFn(self.value);
      });
    }
  }
  function rejectFn(errMsg) { // reject()時執(zhí)行的函數(shù)
    if (self.status === 'pending') {
      self.err = errMsg;
      self.status = 'rejected';
       self.onRejectedArr.forEach(function(catchFn) {
        catchFn(self.err);
      });
    }
  }
  try {
    fn(resolveFn, rejectFn);
  } catch (e) {
    rejectFn(e);
  }
}

實(shí)現(xiàn)then()函數(shù)

創(chuàng)建好了Promise構(gòu)造函數(shù)下一步創(chuàng)建then()函數(shù)

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  // 如果當(dāng)前處于pending狀態(tài),就將函數(shù)壓入對應(yīng)數(shù)組
  var self = this;
  if (self.status === 'pending') {
    self.onFulfilledArr.push(onFulfilled);
    self.onRejectedArr.push(onRejected);
  }
  // fulfilled狀態(tài)就執(zhí)行onFulfilled()方法
  if (self.status === 'fulfilled') {
    onFulfilled(self.value);
  }
  // onFulfilled狀態(tài)就要執(zhí)行onRejected()函數(shù)
  if (self.status === 'rejected') {
    onRejected(self.err);
  }
  return this; // return this是鏈?zhǔn)秸{(diào)用關(guān)鍵
};

到此我們就實(shí)現(xiàn)了自己的myPromise()方法奴璃。最關(guān)鍵的還是Promise的三種狀態(tài),理解了三種狀態(tài)的切換就基本掌握了Promise悉默。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市苟穆,隨后出現(xiàn)的幾起案子抄课,更是在濱河造成了極大的恐慌,老刑警劉巖雳旅,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跟磨,死亡現(xiàn)場離奇詭異,居然都是意外死亡攒盈,警方通過查閱死者的電腦和手機(jī)抵拘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來型豁,“玉大人僵蛛,你說我怎么就攤上這事∮洌” “怎么了充尉?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長氏豌。 經(jīng)常有香客問我喉酌,道長,這世上最難降的妖魔是什么泵喘? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任泪电,我火速辦了婚禮,結(jié)果婚禮上纪铺,老公的妹妹穿的比我還像新娘相速。我一直安慰自己,他們只是感情好鲜锚,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布突诬。 她就那樣靜靜地躺著,像睡著了一般芜繁。 火紅的嫁衣襯著肌膚如雪旺隙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天骏令,我揣著相機(jī)與錄音蔬捷,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛周拐,可吹牛的內(nèi)容都是我干的铡俐。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼妥粟,長吁一口氣:“原來是場噩夢啊……” “哼审丘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勾给,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤滩报,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锦秒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體露泊,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年旅择,在試婚紗的時候發(fā)現(xiàn)自己被綠了惭笑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡生真,死狀恐怖沉噩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情柱蟀,我是刑警寧澤川蒙,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站长已,受9級特大地震影響畜眨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜术瓮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一康聂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胞四,春花似錦恬汁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至导狡,卻和暖如春约巷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背旱捧。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工独郎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓囚聚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親标锄。 傳聞我的和親對象是個殘疾皇子顽铸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

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