原生 js 實現 es6 中的 Promise

        es6 一經推出,Promise 就一直被大家所關注。那麼,爲什麼 Promise 會被大家這樣關注呢?答案很簡單,Promise 優化了回調函數的用法,讓原本需要縱向一層一層嵌套的回調函數實現了橫向的調用,也就是鏈式調用。

       既然  Promise 這麼好用,那它背後的的實現原理是什麼呢?要知道,作爲一個有追求的程序猿,不僅要知其然,還要知其所以然,ok ,下面我就來簡單模擬一下 Promise 的實現!

        首先,我們要知道 Promise 的基本用法是怎樣的。

        

          好,知道了 Promise 的基本用法(我就當你們都會用 ^ ^),那麼我們就來模擬一下它。

          第一步,當然是要一個構造函數了,爲了語義化,我就給它命名爲  _Promise

         我來解釋一下這個構造函數李的屬性都是用來幹什麼的。首先,作爲構造函數的參數傳進來的  resolver,它是一個函數 ,當 _Promise被實例化的時候, resolver  函數會立即執行,它接受兩個參數,分別是 resolverejectresolvereject 就是執行成功和執行失敗的函數。this._status_Promise 的內部狀態,初始化爲 ‘pending’,resolve 函數執行的時候 會把它的值 從 ‘pending’ 變成‘fullfilled’,這也就是說 _Promise 執行成功,反之,reject函數會把它的值 從 ‘pending’ 變成 ‘rejected’。一旦 this._status 的值發生發生了改變之後,它的值就會保持不變,也就是說,它的值 會一直保持在 ‘fullfilled’ 或 ‘rejected’ 狀態 。this._result 是在 rolve 或者 reject 的時候 需要傳遞給 then 函數的值。

         好,接下來我們來看 resolve 和 reject 函數。先上圖:

      resolvereject 函數,在這裏我是直接fanf放在了 _Promise 的原型對象上。當它們被調用的時候,首先需要判斷 _Promise_status 是不是爲 ‘pending’ ,只有在 _status 的值是 ‘pending’ 的時候纔會進行後面的操作。當 _status 的值爲‘pending’的時候,resolve 函數會把 _status的值變成 ‘fullfilled’,如果是 reject 被執行,那麼它就會把 _status 的值變成 ‘rejected’。同時,resolve reject 函數都會把傳遞進來的參數 result 賦值給 this._result ,而這個值會被 之後的 then 函數拿到。

       ok ,接下來看看 then 函數。

          和 resolve 和 reject 函數一樣,then函數也是直接定義在 _Promise 的原型對象上的。

          then函數接收兩個參數,分別是 isResolveisReject ,顧名思義,分別是 resolve (成功)和 reject(失敗) 時調用的函數。因爲考慮到 可能會出現多次鏈式的調用,比如  Promise.then().then().then()這樣的,所以 then 函數 要返回來 一個 _Promise.

那麼 then函數返回來的 _Promise 是哪個呢。這就要看 isResolve isRejected 執行的結果了,如果它們返回來了一個新的 _Promise,那麼我們就需要把這個新的 _Promise 給它 return 出去。

比如這樣的時候:

所以我們就需要判斷一下 isResolve 函數和 isReject 函數的執行結果

 

如果返回的值不是一個新的 _Promise ,那麼我們就把當前的 _Promise 實例返回,也就是 this .

到了這裏,_Promise的模擬也就差不多完成了。還剩下一點,那就是 es6 中 Promise 有一個 catch 函數,我在這裏也簡單模擬了一下,它是專門給 reject 使用的 。

你可以像這樣使用它:

        好了,到此爲止, Promise的模擬就全部完成了。如果大佬們發現了有什麼不足或者錯誤的地方,歡迎在下面留言,我們一起來討論~~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章