日常先打個招呼。。?

今天我們就來完整的實現(xiàn)之前還留有一些小的方法沒實現(xiàn)的Promise。。
回顧:一步一步實現(xiàn)一個符合PromiseA+規(guī)范的Promise庫(1)
? ? ? ? ? ?一步一步實現(xiàn)一個符合PromiseA+規(guī)范的Promise庫(2)
我們都知道,Promise中的常用方法有then、catch、Promise.resolve、Promise.reject、Promise.all、Promise.race這些常用方法,接下來我們就一一來實現(xiàn)它們。
先來實現(xiàn).catch方法。
我們來看以下代碼

我們這里使用的是es6原生的Promise,看到在catch拿到了reject的結(jié)果。而且我們看到,在then方法中只有onfulfilled一個回掉函數(shù)。
而且,catch方法是支持鏈式調(diào)用的,so。。我們需要把這個方法掛載到我們的Promise上。

這樣我們就實現(xiàn)了Promise中的catch方法,是不是很簡單。
可以從之前的測試中看到,.catch方法中的參數(shù)只有一個回掉函數(shù),這個回掉函數(shù)中有一個參數(shù)。我們不難看出來,不管怎樣,這個catch方法拿到的總是我們程序onrejected狀態(tài)下的值。所以我們return一個then方法而且只給這個then方法onrejected回調(diào)。then方法中onfulfilled狀態(tài)我們傳了一個null,為什么?其實我們前面有講到過,請參考我上一篇文章:?一步一步實現(xiàn)一個符合PromiseA+規(guī)范的Promise庫(2)中的onfulfilled和onrejected默認值的問題。這里我們就不再贅述了。
我們再來看看Promose.resolve和Promise.reject這兩個方法。

額。。其實這兩個方法也就是分別返回一個成功和失敗的Promise。這兩個方法作為靜態(tài)方法直接掛在到Promise上即可。
接下來我們實現(xiàn)Promise.all方法。
我們知道Promise.all這個方法是處理多個Promise組成的數(shù)組并且返回一個Promise,當全部的Promise處理完畢后在我們下次調(diào)用then方法時將這個處理結(jié)果的數(shù)組返回。我們看下下面的代碼。

所以我們可以根據(jù)這個原理,來實現(xiàn)我們的Promise.all方法。
我們來看以下代碼。

額。。我覺得已經(jīng)蠻清楚了,再捋一捋。
拿到參數(shù)Promise數(shù)組->遍歷執(zhí)行(調(diào)用其then方法)->存放到返回數(shù)組中->判斷執(zhí)行是否完畢(完畢:返回我們的數(shù)組)。

今天有些晚了,就先實現(xiàn)這幾個吧。race方法等明天或者有空吧。然后我們再來分享下javascript的異步發(fā)展流程。。
最初的callback->Promise->generator函數(shù)->我們現(xiàn)在常用的 async await
就醬:)

更新
race方法的實現(xiàn)。
Promise.race這個方法很有意思。。這個方法也是跟all方法一樣接受一個Promise組成的數(shù)組,但是這些個Promise只要有一個成功了,我們的race方法也就執(zhí)行完畢了,并且返回Promise的執(zhí)行結(jié)果。我們先來看下用法。

我們看到這里race方法中有一個Promise數(shù)組,不過只返回了一個結(jié)果。并且這個race方法也返回了一個Promise,因為我們在接下來的then方法中拿到了之前的執(zhí)行結(jié)果。so。我們來實現(xiàn)下。

我們可以看到,在循環(huán)中我們直接調(diào)用了傳進來的那些Promise,然后當成功時會直接調(diào)用我們返回的Promise的resolve方法把執(zhí)行的結(jié)果返回出去。
到這里我們基本上就實現(xiàn)了一個比較完整的Promise,當然這個Promise還相對簡單。不過我們也蠻不錯了。

接下來我們看一下js的異步發(fā)展流程.
我們都知道以前比如說我們在處理異步的時候通常會有這樣的代碼。
回調(diào)函數(shù)
如果{
? ? ? ? 我是說{
? ? ? ? ? ? ? ? 能不能{
? ? ? ? ? ? ? ? ? ? ? ? ? ? 干一件事{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
????????????????}
????????}
}
丑的一批。。
。。其實也還好,主要是還蠻好看的。但是如果我們異步做的多了,回調(diào)地獄自然不可避免。所以Promise應運而生。
我們再來看下Promise
一般的代碼是這樣
Promise.resolve().then().then()......
then多了也不咋好看。。而且一個then中兩個回調(diào),再返回Promise。。EMMMMM。。
然后出現(xiàn)的就是我們的generator函數(shù)。
generator

如果用過generator函數(shù)的小伙伴們應該知道。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方法中。
我們可以自己實現(xiàn)一個co庫,其實也是很簡單的一個方法。

我們看一下測試結(jié)果

發(fā)現(xiàn)依舊是沒有問題的。這樣我們就寫了一個簡單的co庫來幫助我們使用generator函數(shù)。
最后一個就是我們的async和await。
async-await

我們可以看到,async和await,使用起來跟generator函數(shù)類似,其實呢,async和await就是generator和yield的一種語法糖,
當然這個語法糖的實現(xiàn)比較復雜,我們?nèi)绻袝r間的話還會跟大家一起實現(xiàn)一下。我們這里先看看他的用法。
我們可以看到,async方法一樣的返回了一個Promise,并且相當于自動執(zhí)行了generator中的next方法,使得我們不必再耗費精力去處理執(zhí)行器,在開發(fā)中使我們的開發(fā)體驗變好了許多。。畢竟代碼還是簡潔明了好一點。。。

好了,一路走來我們也算比較完整的了解了Promise的實現(xiàn)原理,我們也算是完成了一個符合Promise/A+規(guī)范的Promise庫。然后我們還了解了js近些年來的異步發(fā)展,有沒有覺得自己很棒呢。。(反正我是覺得我們蠻厲害)
最后,希望大家不管是生活還是學習和工作中都可以更好。再次感謝大家可以看到這里,謝謝。
就醬,Bye~
