通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例

過去在寫 JavaScript 使用的同步延遲時,都是用非同步的 setTimeout 加上 callback 來實現,但如果有很多個任務或流程要執行,就得用上一大堆的 callback,然而 JavaScript 裡的 Promise ,剛好就可以用來解決同步與非同步的問題,讓整個延遲的過程可以很漂亮簡潔且同步的「串」在一起。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例


同步非同步

一般來說 JavaScript 裡面有分成同步 sync 和非同步 async,在同步模式下,每個任務必須按照順序執行,後面的任務必須等待前面的任務執行完成,非同步模式則相反,後面的任務不用等前面的,各自執行各自的任務,例如setTimeout、setInterval都是這種模式。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例

如果 JavaScript 寫成下面這樣,結果並不會如果們預期的「等待一秒後出現 A,出現 A 後等待一秒再出現 B」,反而是等待一秒後 A、B 同時出現,所以變成傳統在實作的時候,就要寫很多的 callback 來滿足同步的情況。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例


Promise

為了解決同步非同步的問題,我開始學習 Promise,剛接觸 Promise 的時候實在是有點頭昏腦脹,因為網路上的資料很多,但總找不到一個合適的範例展示,導致一直沒辦法深入理解,後來終於找到了幾個合適的教程,也讓我終於踏入了 Promise 的世界。

簡單來說,Promise 就是「承諾」,可以想像成 A 承諾 B 要去辦事,辦完之後才會回報結果,而這個結果只有兩種狀況:成功與失敗,不會有處於成功失敗不明的中間狀況。

所以換成程式的講法,要使用 Promise,一開始要先 new 一個 Promise 對象實例,其中的建構式包含兩個參數:resolve ( 成功 ) 與 reject ( 失敗 )。

基本創建 Promise 的方法如下,resolve 在函式或流程成功,或有合法值的狀況下會執行,reject 則是在失敗或有錯誤的時候會執行,resolve 和 reject 都有一個回傳值,可將這個會傳值透過.then傳給下一個流程。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例


同步延遲

大概知道用法之後,先來個簡單的例子,建立一個 delay 的流程,流程裡有個setTimeout,在延遲一秒後,將 resolve 成功的值通過.then傳下去。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例

不過這樣只有寫,跟純粹setTimeout的結果看起來沒什麼差異,因為只延遲了一次而已,現在換個例子,讓顯示的文字延遲三次,每次都延遲一秒,如果是傳統setTimeout的寫法就會像下面這樣:三個流程 + 兩個 callback,不僅越來越難閱讀,維護成本相對也越來越高。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例

如果換成 Promise 的做法,就可以把 setTimeout 放到 Promise 裡面,同時可以設定一個變數作為延遲的毫秒數,接下來就可以使用.then來做串接,在每一個 then 裡頭,再 return 一個 Promise 實例,就可以繼續使用.then串接下去,實際完成之後,應該就會看到 123 依序隔一秒才出現,寫法上也就更為清楚簡潔。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例


resolve 回傳值

當 resolve 有合法值的時候,可將這個值傳遞下去使用,但 resolve 只能有一個回傳值 (resolve(value)),所以如果有兩個以上,則必須通過數組來傳遞,舉例來說 delay 有兩個參數,第一個參數是顯示的文字,第二個則是延遲的秒數,透過resolve([r,s]);就能不斷地將值傳遞下去,結果就會是先顯示「a 0」,延遲一秒後顯示「b 1000」,延遲兩秒後顯示「c 2000」。

通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例


小結

以上就是通過 Promise + setTimeout 所實現的同步延遲,但在 ES7 開始其實有 async、await、delay 的用法 ( 聽說用過就會愛上 ),就等瀏覽器全面支持後,應該就可以更方便的使用了!


通過Promise + setTimeout,實現JavaScript 的同步延遲簡單示例


分享到:


相關文章: