0%

[JS] 講座筆記:JS Promise 實戰教學

本篇筆記來自 2020.2.26 六角學院線上研討會,講者為偷米騎巴哥的 Tommy。在這一次講座中,Tommy 老師為大家複習了非同步行為與 Queue 的概念,並接續介紹了使非同步行為依序進行的四種方法。

當我們有 3 個 setTimeout() 時,我們可以使它們按照順序執行;但是當我們有 3 個 AJAX 時,由於變因太多、無法確定各自回傳的時間,因此不一定能照順序執行。

要解決非同步無法依序執行的問題,第一個方法是使用 callback function。

讓非同步依序執行 解法一:callback

三個 setTimeout() 個別用 function 包起來,且各個 function 都帶入一個 callback 參數。

呼叫 function A 時,同時定義 callback 的任務內容,如此一來就可以先印出 'A' 再印出 'OK'

運用這個原理,就可以把 function B 當作 function A 的 callback,把 function C 當作 function B 的 callback。

但是這種做法一旦遇到太多函式要依序執行時,就會變成 callback hell,將會很難去分辨程式碼。

讓非同步依序執行 解法二:Generator

  • 在 function 後面加一個 *,執行時會得到一個 generator 物件。
  • 在 for 迴圈中使用 yield 關鍵字:代表暫停,先跳出 function,等之後在 function 外面用 函式名稱.next() 呼叫時,才會再回到 function 內部繼續執行。
  • generator 物件會帶出 done 特性
  • arguments : 類陣列物件,可取得所有傳入 function 的參數
  • 遞迴:在函式裡呼叫函式本身

for 迴圈跑到最後一次時,done 的值為 true

recursion() 中使用 .next() 呼叫函式與遞迴,讓 function A, function B, function C 依序執行:

小結:最後一行,在 generator() 帶入多個函式作為參數,就能依序執行並避免 callback hell。

讓非同步依序執行 解法三:Promise

  • 一個封裝 Promise 的函式
  • Promise 的 callback function 要帶入兩個參數:resolve (成功時呼叫),以及 reject (失敗時呼叫)。

非同步成功時,就會執行 resolveresolve 執行後,就會執行 .then() 的內容;反過來說,.then() 的執行仰賴 resolve 是否執行。

非同步失敗時,Promise 會執行 rejectreject 必須準備對應的函式,這個函式是針對單一的 Promise,在失敗時執行的方案。

在非同步失敗時執行對應的行為也能用 catch 達成,catch 的意思是,只要其中一個 Promise 沒成功執行,就跳到 catch

讓非同步依序執行 解法四:async…await

  • ES7 語法,要搭配 Promise 使用
  • async + function:宣告這個函式是非同步
  • await + Promise:依序執行函式
  • 條件:asyncawait 一定要搭配使用,不能只用 await 卻不用 async

reject 時與 try...catch 搭配使用,reject() 括號內的內容會傳到 catch(e)e 參數,也可以直接在 reject() 括號內放入 Error 物件(JS 原生錯誤物件)。

三個函式非同步失敗時想要不同的錯誤訊息:

實務上使用 XMLHttpRequest 時的寫法:

參考資料

slides 簡報
function*
JavaScript Promise:簡介
JavaScript Promise 全介紹