日常先打個招呼轻庆。椒振。?
今天我們就來完整的實(shí)現(xiàn)之前還留有一些小的方法沒實(shí)現(xiàn)的Promise碰酝。。
回顧:一步一步實(shí)現(xiàn)一個符合PromiseA+規(guī)范的Promise庫(1)
? ? ? ? ? ?一步一步實(shí)現(xiàn)一個符合PromiseA+規(guī)范的Promise庫(2)
我們都知道,Promise中的常用方法有then乱投、catch咽笼、Promise.resolve、Promise.reject戚炫、Promise.all剑刑、Promise.race這些常用方法,接下來我們就一一來實(shí)現(xiàn)它們双肤。
先來實(shí)現(xiàn).catch方法施掏。
我們來看以下代碼
我們這里使用的是es6原生的Promise,看到在catch拿到了reject的結(jié)果。而且我們看到茅糜,在then方法中只有onfulfilled一個回掉函數(shù)七芭。
而且,catch方法是支持鏈?zhǔn)秸{(diào)用的蔑赘,so狸驳。。我們需要把這個方法掛載到我們的Promise上缩赛。
這樣我們就實(shí)現(xiàn)了Promise中的catch方法耙箍,是不是很簡單。
可以從之前的測試中看到峦筒,.catch方法中的參數(shù)只有一個回掉函數(shù)究西,這個回掉函數(shù)中有一個參數(shù)。我們不難看出來物喷,不管怎樣卤材,這個catch方法拿到的總是我們程序onrejected狀態(tài)下的值。所以我們return一個then方法而且只給這個then方法onrejected回調(diào)峦失。then方法中onfulfilled狀態(tài)我們傳了一個null扇丛,為什么?其實(shí)我們前面有講到過尉辑,請參考我上一篇文章:?一步一步實(shí)現(xiàn)一個符合PromiseA+規(guī)范的Promise庫(2)中的onfulfilled和onrejected默認(rèn)值的問題帆精。這里我們就不再贅述了。
我們再來看看Promose.resolve和Promise.reject這兩個方法隧魄。
額卓练。。其實(shí)這兩個方法也就是分別返回一個成功和失敗的Promise购啄。這兩個方法作為靜態(tài)方法直接掛在到Promise上即可襟企。
接下來我們實(shí)現(xiàn)Promise.all方法。
我們知道Promise.all這個方法是處理多個Promise組成的數(shù)組并且返回一個Promise,當(dāng)全部的Promise處理完畢后在我們下次調(diào)用then方法時將這個處理結(jié)果的數(shù)組返回狮含。我們看下下面的代碼顽悼。
所以我們可以根據(jù)這個原理曼振,來實(shí)現(xiàn)我們的Promise.all方法。
我們來看以下代碼蔚龙。
額冰评。。我覺得已經(jīng)蠻清楚了木羹,再捋一捋甲雅。
拿到參數(shù)Promise數(shù)組->遍歷執(zhí)行(調(diào)用其then方法)->存放到返回數(shù)組中->判斷執(zhí)行是否完畢(完畢:返回我們的數(shù)組)。
今天有些晚了汇跨,就先實(shí)現(xiàn)這幾個吧务荆。race方法等明天或者有空吧。然后我們再來分享下javascript的異步發(fā)展流程穷遂。。
最初的callback->Promise->generator函數(shù)->我們現(xiàn)在常用的 async await
就醬:)
更新
race方法的實(shí)現(xiàn)娱据。
Promise.race這個方法很有意思蚪黑。。這個方法也是跟all方法一樣接受一個Promise組成的數(shù)組中剩,但是這些個Promise只要有一個成功了忌穿,我們的race方法也就執(zhí)行完畢了,并且返回Promise的執(zhí)行結(jié)果结啼。我們先來看下用法掠剑。
我們看到這里race方法中有一個Promise數(shù)組,不過只返回了一個結(jié)果郊愧。并且這個race方法也返回了一個Promise朴译,因?yàn)槲覀冊诮酉聛淼膖hen方法中拿到了之前的執(zhí)行結(jié)果。so属铁。我們來實(shí)現(xiàn)下眠寿。
我們可以看到,在循環(huán)中我們直接調(diào)用了傳進(jìn)來的那些Promise焦蘑,然后當(dāng)成功時會直接調(diào)用我們返回的Promise的resolve方法把執(zhí)行的結(jié)果返回出去盯拱。
到這里我們基本上就實(shí)現(xiàn)了一個比較完整的Promise,當(dāng)然這個Promise還相對簡單例嘱。不過我們也蠻不錯了狡逢。
接下來我們看一下js的異步發(fā)展流程.
我們都知道以前比如說我們在處理異步的時候通常會有這樣的代碼。
回調(diào)函數(shù)
如果{
? ? ? ? 我是說{
? ? ? ? ? ? ? ? 能不能{
? ? ? ? ? ? ? ? ? ? ? ? ? ? 干一件事{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
????????????????}
????????}
}
丑的一批拼卵。奢浑。
。间学。其實(shí)也還好殷费,主要是還蠻好看的印荔。但是如果我們異步做的多了,回調(diào)地獄自然不可避免详羡。所以Promise應(yīng)運(yùn)而生仍律。
我們再來看下Promise
一般的代碼是這樣
Promise.resolve().then().then()......
then多了也不咋好看。实柠。而且一個then中兩個回調(diào)水泉,再返回Promise。窒盐。EMMMMM草则。。
然后出現(xiàn)的就是我們的generator函數(shù)蟹漓。
generator
如果用過generator函數(shù)的小伙伴們應(yīng)該知道炕横。generator可以在執(zhí)行過程中多次返回,所以它看上去就像一個可以記住執(zhí)行狀態(tài)的函數(shù)葡粒,generator函數(shù)通常配合Promise和tj寫的co庫來使用份殿。由于generator函數(shù)會產(chǎn)生一個執(zhí)行器,我們要使用這個執(zhí)行器的next方法來執(zhí)行我們的異步方法去得到我們想要的值嗽交。
如果有些小伙伴還不明白generator的工作方式卿嘲,可以去看一下他的使用方法。->Generator 函數(shù)的含義與用法
co庫可以幫助我們不去管執(zhí)行器中的next方法夫壁,返回一個Promise并且把執(zhí)行結(jié)果放到返回的Promise的then方法中拾枣。
我們可以自己實(shí)現(xiàn)一個co庫,其實(shí)也是很簡單的一個方法盒让。
我們看一下測試結(jié)果
發(fā)現(xiàn)依舊是沒有問題的梅肤。這樣我們就寫了一個簡單的co庫來幫助我們使用generator函數(shù)。
最后一個就是我們的async和await糯彬。
async-await
我們可以看到凭语,async和await,使用起來跟generator函數(shù)類似撩扒,其實(shí)呢似扔,async和await就是generator和yield的一種語法糖,
當(dāng)然這個語法糖的實(shí)現(xiàn)比較復(fù)雜搓谆,我們?nèi)绻袝r間的話還會跟大家一起實(shí)現(xiàn)一下炒辉。我們這里先看看他的用法。
我們可以看到泉手,async方法一樣的返回了一個Promise黔寇,并且相當(dāng)于自動執(zhí)行了generator中的next方法,使得我們不必再耗費(fèi)精力去處理執(zhí)行器斩萌,在開發(fā)中使我們的開發(fā)體驗(yàn)變好了許多缝裤。屏轰。畢竟代碼還是簡潔明了好一點(diǎn)。憋飞。霎苗。
好了,一路走來我們也算比較完整的了解了Promise的實(shí)現(xiàn)原理榛做,我們也算是完成了一個符合Promise/A+規(guī)范的Promise庫唁盏。然后我們還了解了js近些年來的異步發(fā)展,有沒有覺得自己很棒呢检眯。厘擂。(反正我是覺得我們蠻厲害)
最后,希望大家不管是生活還是學(xué)習(xí)和工作中都可以更好锰瘸。再次感謝大家可以看到這里刽严,謝謝。
就醬避凝,Bye~