摘要:今天我們來自己手寫一個符合規(guī)范的庫。是異步編程的一種解決方案,比傳統(tǒng)的解決方案回調(diào)函數(shù)和事件更合理和更強大。我們可以看到,其實就是一個構(gòu)造函數(shù)。所以說我們的數(shù)組里存的是一個一個的的回調(diào)函數(shù),也就是一個一個。
今天我們來自己手寫一個符合PromiseA+規(guī)范的Promise庫。大家是不是很激動呢??
才沒有。。
我們都知道。在現(xiàn)在的前端開發(fā)中,Promise這個東西基本上所有的開發(fā)中都會用到。
那必然有些萌新就會問了,Promise到底是個什么東西呢。
按照規(guī)范來說。Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大。它由社區(qū)最早提出和實現(xiàn),ES6 將其寫進(jìn)了語言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對象。
通俗來講。。這個東西就是為了解決我們平常的回調(diào)函數(shù),避免回調(diào)地獄的一種解決方案。所以說這個東西大家不僅要會用哦,還應(yīng)該知道他的一些原理。so,我們一起來實現(xiàn)下吧。
接下來我們先看一個簡單的Promise。
這個就是es6標(biāo)準(zhǔn)中的Promise。我們可以看到,其實Promise就是一個構(gòu)造函數(shù)。
這個構(gòu)造函數(shù)中只有一個參數(shù)。這個參數(shù)在Promise/A+規(guī)范中被稱為executor(執(zhí)行者..我覺得叫執(zhí)行器蠻好)。
因為這個執(zhí)行器是為了執(zhí)行后面的resolve(決定)和reject(拒絕)方法。呃...其實你可以把resolve看作是成功,把reject看做失敗。
當(dāng)然了我們還可以根據(jù)自己定義的規(guī)則來進(jìn)行Promise中resolve和reject的調(diào)用,不過這是用法,我們這里就當(dāng)大家會用了。。
然后我們可以看到,在構(gòu)造函數(shù)的實例p中還有一個then方法。這里我們就要想了,既然是構(gòu)造函數(shù)的實例上哪必然這個函數(shù)是掛在到這個構(gòu)造函數(shù)的原型上。
還有很重要的一點就是我們可以想一下,在Promise中這個Promise的當(dāng)前狀態(tài)是一個問題。在A+規(guī)范中規(guī)定:一個Promise只有三種狀態(tài),我們看圖
什么意思呢。。
大致的意思就是說,一個Promise有且僅有(pending->等待,fulfilled->已執(zhí)行,rejected->已拒絕)這三種狀態(tài)中的一種(ps:我曾經(jīng)看到過一個詞->懸而未決用來形容pending也不錯 :)。
我們知道了這些,接下來我們就來手動實現(xiàn)一個簡單的。
繼續(xù)。。。。
這里我們要說一下,貌似剛才忘說了。。。
我們通過這張圖來看一下,當(dāng)目前的狀態(tài)為pending時。我們可以將pending狀態(tài)改變?yōu)閒ulfilled或者rejected中的一種。然而我們要記住,之前已經(jīng)提到過Promise的狀態(tài)必須是三種之一。而且,如果一旦成功就不能失敗,一旦失敗就不能成功。
接下來我們依據(jù)上面狀態(tài)的描述來繼續(xù)、、、
這里當(dāng)我們調(diào)用resolve和reject的時候我們需要做出狀態(tài)判斷,只有是pending狀態(tài)的時候才可以改變狀態(tài)為其他兩種的任意一種,如果不是:例如
我們處理完了resolve和reject內(nèi)置的邏輯,這里有一個問題。在開發(fā)中,當(dāng)Promise的執(zhí)行遇到錯誤時,會直接變成rejected狀態(tài),大家應(yīng)該都知道,也就是下面的處理。
我們在Promise的執(zhí)行過程中如果捕獲到異常,就可以直接調(diào)用reject來結(jié)束Promise。
接下來我們看then方法。
這樣我們就實現(xiàn)了一個簡單的Promise(才沒有。。。這才哪到哪),我們來試下效果吧。
別忘了導(dǎo)出我們的Promise。。
我們看到下面的輸出結(jié)果,哇!!好激動有沒有(才沒有激動),我也實現(xiàn)了一個Promise!
但是!有一個問題,我們是不是弄丟了一個狀態(tài)???
what??哪個??仔細(xì)想一下好像是‘pending’丟掉了。。
so?那咋辦。
有人可能會說了,不是出了成功就是失敗嗎,為什么會有等待狀態(tài)呢,我們來思考一下下面的代碼。
話說Promise應(yīng)該都是支持異步的吧?就像上面的代碼,異步執(zhí)行resolve的時候我們是不是已經(jīng)吧值給弄丟了?
并且我們想一下,弄丟這個值得一段時間是不是就是等待態(tài)也就是‘pending’的時候。。
所以,我們要怎么處理這個pending呢?
我們想一下,在executor中的resolve和reject是不是都會吧我們傳入的值,傳到then方法的onfulfilled和onrejected中?另外,我們在then方法中做了對目前Promise的狀態(tài)的判斷。
所以我們在then方法中去處理‘pending’狀態(tài)。
怎么去處理呢?我們可以在Promise中掛載兩個數(shù)組。
為什么?這兩個數(shù)組的作用是為了記錄pending狀態(tài)下的onfulfilled和onreject函數(shù)。我們來看then中的代碼。
我們可以看到在pending狀態(tài)下,這兩個數(shù)組分別記錄了各自對應(yīng)的then的回調(diào)函數(shù),并且保存起來。
我們來捋一捋思路。
所以說我們的數(shù)組里存的是一個一個的then的回調(diào)函數(shù),也就是一個一個function。
所以我們要在resolve和reject方法觸發(fā)的時候,去便利我們的數(shù)組并且執(zhí)行其中的方法,并且呢還要把我們成功的原因(self.value)和失敗的原因(self.reason)放到我們的回調(diào)方法中去。說了這么多有點繞。。上代碼
這樣就解決了異步的問題。我們再來測試一下。
代碼剛開始運行。
2秒后。。。
這時我們就拿到了異步的值,是不是很開心!(有點,嘿嘿)
再看一下我們寫的全部的代碼:
到這里我們簡單了解了Promise的一小部分原理,并且實現(xiàn)了一個非常簡單的Promise。今天就先寫到這里,在下一章中我們會繼續(xù)了解Promise中的then方法是如何鏈?zhǔn)秸{(diào)用的,以及鏈?zhǔn)秸{(diào)用中的許多坑。。。
好啦,謝謝大家看到這里。感謝。
再次感謝。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/93584.html
摘要:我們都知道,方法中有和兩個回調(diào)函數(shù),所以我們要處理一下這兩個回調(diào)函數(shù)。我們實現(xiàn)了異步調(diào)用,在方法中返回或者值,實現(xiàn)了方法中可以沒有回調(diào)函數(shù)也能把執(zhí)行結(jié)果傳入下一次的方法中。 Hello everybody。我又來啦,還記得我們上一張實現(xiàn)的內(nèi)容嗎? showImg(https://segmentfault.com/img/bV6UaU?w=102&h=95); 上一張我們實現(xiàn)了一個簡單的...
摘要:簡單實現(xiàn)前言你可能知道,的任務(wù)執(zhí)行的模式有兩種同步和異步。你已經(jīng)實現(xiàn)了方法方法是一個很好用的方法。感興趣的朋友可以自行去研究哈附上代碼完整的實現(xiàn)個人博客鏈接 Promise 簡單實現(xiàn) 前言 你可能知道,javascript 的任務(wù)執(zhí)行的模式有兩種:同步和異步。 異步模式非常重要,在瀏覽器端,耗時很長的操作(例如 ajax 請求)都應(yīng)該異步執(zhí)行,避免瀏覽器失去響應(yīng)。 在異步模式編程中,我...
摘要:不同的的實現(xiàn)需要可以相互調(diào)用,搞清楚了標(biāo)準(zhǔn)之后,開始動手吧構(gòu)造函數(shù)產(chǎn)生一個對象有很多種方法,構(gòu)造函數(shù)是看起來最面向?qū)ο蟮囊环N,而且原生實現(xiàn)也是使用的構(gòu)造函數(shù),因此我也決定使用構(gòu)造函數(shù)的方法。 -- What i cant create, i dont understant 前言 實現(xiàn)Promise的目的是為了深入的理解Promies,以在項目中游刃有余的使用它。完整的代碼見gitHub...
摘要:以上代碼,可以完美通過所有用例。在的函數(shù)中,為何需要這個同樣是因為規(guī)范中明確表示因此我們需要這樣的來確保只會執(zhí)行一次。其他情況,直接返回以該值為成功狀態(tài)的對象。 Promise是前端面試中的高頻問題,我作為面試官的時候,問Promise的概率超過90%,據(jù)我所知,大多數(shù)公司,都會問一些關(guān)于Promise的問題。如果你能根據(jù)PromiseA+的規(guī)范,寫出符合規(guī)范的源碼,那么我想,對于面試...
摘要:嗝首先,我們通過字面可以看出來是一種解決方案,而且還有兩種傳統(tǒng)的解決方案回調(diào)函數(shù)和事件,,那么我們就來先聊聊這兩種方案。 前言 雖然今年已經(jīng)18年,但是今天還是要繼續(xù)聊聊ES6的東西,ES6已經(jīng)過去幾年,可是我們對于ES6的語法究竟是掌握了什么程度,是了解?會用?還是精通?相信大家和我一樣都對自己有著一個提升的心,對于新玩具可不能僅僅了解,對于其中的思想才是最吸引人的,所以接下來會通過...
閱讀 3115·2023-04-25 15:02
閱讀 2804·2021-11-23 09:51
閱讀 2030·2021-09-27 13:47
閱讀 1984·2021-09-13 10:33
閱讀 957·2019-08-30 15:54
閱讀 2640·2019-08-30 15:53
閱讀 2853·2019-08-29 13:58
閱讀 881·2019-08-29 13:54