es6 一經推出,Promise 就一直被大家所關注。那麼,爲什麼 Promise 會被大家這樣關注呢?答案很簡單,Promise 優化了回調函數的用法,讓原本需要縱向一層一層嵌套的回調函數實現了橫向的調用,也就是鏈式調用。
既然 Promise 這麼好用,那它背後的的實現原理是什麼呢?要知道,作爲一個有追求的程序猿,不僅要知其然,還要知其所以然,ok ,下面我就來簡單模擬一下 Promise 的實現!
首先,我們要知道 Promise 的基本用法是怎樣的。
好,知道了 Promise 的基本用法(我就當你們都會用 ^ ^),那麼我們就來模擬一下它。
第一步,當然是要一個構造函數了,爲了語義化,我就給它命名爲 _Promise
我來解釋一下這個構造函數李的屬性都是用來幹什麼的。首先,作爲構造函數的參數傳進來的 resolver,它是一個函數 ,當 _Promise被實例化的時候, resolver 函數會立即執行,它接受兩個參數,分別是 resolve 和 reject。resolve 和 reject 就是執行成功和執行失敗的函數。this._status 是 _Promise 的內部狀態,初始化爲 ‘pending’,resolve 函數執行的時候 會把它的值 從 ‘pending’ 變成‘fullfilled’,這也就是說 _Promise 執行成功,反之,reject函數會把它的值 從 ‘pending’ 變成 ‘rejected’。一旦 this._status 的值發生發生了改變之後,它的值就會保持不變,也就是說,它的值 會一直保持在 ‘fullfilled’ 或 ‘rejected’ 狀態 。this._result 是在 rolve 或者 reject 的時候 需要傳遞給 then 函數的值。
好,接下來我們來看 resolve 和 reject 函數。先上圖:
resolve 和 reject 函數,在這裏我是直接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函數接收兩個參數,分別是 isResolve 和 isReject ,顧名思義,分別是 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的模擬就全部完成了。如果大佬們發現了有什麼不足或者錯誤的地方,歡迎在下面留言,我們一起來討論~~~~