摘要:我們都知道,方法中有和兩個回調函數,所以我們要處理一下這兩個回調函數。我們實現了異步調用,在方法中返回或者值,實現了方法中可以沒有回調函數也能把執行結果傳入下一次的方法中。
Hello everybody。我又來啦,還記得我們上一張實現的內容嗎?
上一張我們實現了一個簡單的Promise。我們實現了Promise內部的簡單流程和then方法,并且實現了Promise的異步調用。但是我們也留下了一些問題。。。
由于今天的代碼是基于上一次我們實現的內容,所以不甚了解的小伙伴們可以去看我上一篇文章。。
文章地址:一步一步實現一個符合PromiseA+規范的Promise庫(1)
問題一:then方法的鏈式調用
我們都知道,一個Promise是可以在其中再次返回Promise的(當然也可以返回一個普通的值)。而且呢,返回的Promise或者返回的普通值我們需要去拿到它的值并且回傳給我們下一次的then方法中。比如:
當然我們也可以在then方法中返回一個Promise;
所以問題就來了。
問題二:如果在then方法中返回Promise或者普通值的情況,我們需要怎么處理。
so,開搞。
我們先來處理第一個問題,讓我們的then方法支持鏈式調用,并且能接受普通值。
我們先來修改then方法中的對于成功狀態(onfulfilled)的判斷,因為下面的跟他是相同的道理。
這里我們首先來看定義的Promise2。為什么要定義這樣一個變量呢?
我們要知道,如果要實現Promise中then方法的鏈式調用。當第一個then運行完畢并且把返回值給我們之后,我們也要返回這個值。
我們不禁要問了?一個值怎么怎么會有then方法呢?所以我們要把這個值包裝成一個Promise對象給返回出去。
所以說,我們需要使每個狀態都返回一個Promise。。說的有點多。我們來測試一下。
我們接著改下面兩個狀態。
我們來捋一捋。通過測試。
我們看到代碼運行了2.496秒,我們的測試結果是正確的;
到這里我們就解決了then方法鏈式調用并且在then方法中返回一個普通值到下一次then方法的成功狀態中。
是不是感覺很爽
接下來我們解決第二個問題。我們是需要允許在then方法中返回Promise的。。所以,我們也要處理這種情況。
Let us try to do it
展示一下我深厚的英語功底
其實很簡單,我們需要一個統一的處理函數來進行在then中返回Promise的處理。。
我們先新建一個方法叫做resolvePromise(Promise的決定)
在規范中說道。
什么意思呢,就是說如果Promise2和x指向的是同一個對象,我們這里就要把需要返回的Promise2置為reject并且要返回一個類型錯誤。看下面的代碼
額,就是這樣
然后我們描述一下細節。。
emmmmmmmm...
這TM有點細節。。
好了不逗了,我們在代碼里面分析的很清楚了。我們來捋一捋思路。
在then方法中是可以返回一個Promise的對吧,然后我們拿到了then方法的執行結果,也就是可能是一個Promise或者是一個普通值(也就是x)。然后我們對這個x進行判斷,我們首先要判斷這個x是不是一個Promise對吧。
如果不是我們可以直接返回x,如果是的話,我們應該知道,Promise都會有then方法。我們接下來就需要判斷這個then方法是不是一個function。如果不是我們就直接返回這個then的值,emmm...他應給就是一個普通值。
如果這個then方法是一個function我們就可以直接去執行他。我們在兩個回調中進行操作,如果執行的是onfulfilled則我們進行了關鍵的一步,就是遞歸調用我們的resolvePromise方法去看我們的onfulfilled傳進來的參數是否還是一個Promise,,就這樣一直調用,,直到x或者x.then是一個普通的值為止,然后我們就可以返回這個值,也就是resolve我們最后的值。
當然我們這里加了try{}catch(){}還是為了避免程序運行中的錯誤。
然后我們就可以把我們之前的狀態判斷中的resolve替換成我們的resolvePromise方法,例如:
當然下面的pending狀態也是一樣的。
到這里我們的Promise已經實現的差不多了。但是還有一個問題。我們思考以下代碼;
上面代碼用的是ES6的原生的Promise
what?我們可以看到,第一個then方法中并沒有任何東西,然而我們第二個then中卻拿到了promies中resolve的值。
我們都知道,then方法中有onfulfilled和onreject兩個回調函數,所以我們要處理一下這兩個回調函數。
注意onrejected中的default函數返回是用了throw。因為我們要返回到下一次的reject中
我們可以在then方法中處理一下這兩個回調。判斷一下他們的類型,如果類型是function就代表這兩個回調是有東西的。不然呢我們就返回一個默認的匿名函數,這個函數的參數就是上一次Promise返回的值,也就是當我們再次執行onfulfilled或者onrejected的時候就可以直接拿到這個值了。也就完成了我們想要的效果。
現在,我們基本上就實現了一個比較完整地Promise。我們實現了Promise異步調用,在then方法中返回Promise或者值,實現了then方法中可以沒有回調函數也能把執行結果傳入下一次的then方法中。
當然我們基本清楚了Promise的基本原理,以后我們就可以說我們既會使用又可以實現一個Promise。
當然還有一些小小的問題,就是Promise中有許多方法我們沒有實現。例如:
Promise.resolve() . Promise.reject() ..還有.catch()方法 Promise.all()方法等等
在下一篇文章中,我們會一一的去實現這些方法,并且會介紹一下前端開發這些年的異步發展流程
最初的callback->Promise->generator函數->我們現在常用的 async await
好了,就到這里吧。看到這里蠻不容易,謝謝大家。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93732.html
摘要:今天我們來自己手寫一個符合規范的庫。是異步編程的一種解決方案,比傳統的解決方案回調函數和事件更合理和更強大。我們可以看到,其實就是一個構造函數。所以說我們的數組里存的是一個一個的的回調函數,也就是一個一個。 今天我們來自己手寫一個符合PromiseA+規范的Promise庫。大家是不是很激動呢?? showImg(https://segmentfault.com/img/bV6t4Z?...
摘要:簡單實現前言你可能知道,的任務執行的模式有兩種同步和異步。你已經實現了方法方法是一個很好用的方法。感興趣的朋友可以自行去研究哈附上代碼完整的實現個人博客鏈接 Promise 簡單實現 前言 你可能知道,javascript 的任務執行的模式有兩種:同步和異步。 異步模式非常重要,在瀏覽器端,耗時很長的操作(例如 ajax 請求)都應該異步執行,避免瀏覽器失去響應。 在異步模式編程中,我...
摘要:不同的的實現需要可以相互調用,搞清楚了標準之后,開始動手吧構造函數產生一個對象有很多種方法,構造函數是看起來最面向對象的一種,而且原生實現也是使用的構造函數,因此我也決定使用構造函數的方法。 -- What i cant create, i dont understant 前言 實現Promise的目的是為了深入的理解Promies,以在項目中游刃有余的使用它。完整的代碼見gitHub...
摘要:以上代碼,可以完美通過所有用例。在的函數中,為何需要這個同樣是因為規范中明確表示因此我們需要這樣的來確保只會執行一次。其他情況,直接返回以該值為成功狀態的對象。 Promise是前端面試中的高頻問題,我作為面試官的時候,問Promise的概率超過90%,據我所知,大多數公司,都會問一些關于Promise的問題。如果你能根據PromiseA+的規范,寫出符合規范的源碼,那么我想,對于面試...
摘要:嗝首先,我們通過字面可以看出來是一種解決方案,而且還有兩種傳統的解決方案回調函數和事件,,那么我們就來先聊聊這兩種方案。 前言 雖然今年已經18年,但是今天還是要繼續聊聊ES6的東西,ES6已經過去幾年,可是我們對于ES6的語法究竟是掌握了什么程度,是了解?會用?還是精通?相信大家和我一樣都對自己有著一個提升的心,對于新玩具可不能僅僅了解,對于其中的思想才是最吸引人的,所以接下來會通過...
閱讀 3615·2021-11-22 09:34
閱讀 3186·2021-11-15 11:38
閱讀 3039·2021-10-27 14:16
閱讀 1233·2021-10-18 13:35
閱讀 2424·2021-09-30 09:48
閱讀 3429·2021-09-29 09:34
閱讀 1626·2019-08-30 15:54
閱讀 1818·2019-08-26 11:57