callback hell
JavaScript 中有很多非同步的事件,例如:AJAX、setTimeout、各種 event 事件(click,onchange…)等,由於 JavaScript 為單執行緒的程式語言(參考這邊),這些事件我們很常使用 callback,在一層包一層後就會出現知名的 callback 地獄,而 ES6 開始新增了 Promise 物件就是為了解決此問題而生的。
Promise 的狀態與流程
Promise 承諾,顧名思義就是「保證達到某個條件之後才會再做什麼事情」。
Promise 物件會有以下這幾種狀態:
- pending: 等待中的初始狀態
- fulfilled: 正確完成
- rejected: 已拒絕,操作失敗
剛進入 Promise 時,我們會進入 pending (等待事件完成)的狀態,接下來會依據事件的成功與否來回傳成功或拒絕的 callback,通常我們會使用 resolve
、reject
兩個變數來傳送成功與失敗的訊息(資料)。
1 | let myFirstPromise = new Promise((resolve, reject) => { |
以下圖為範例,ASin 一開始在原地準備要跑步,此時他有兩種結果,一種是他正確的完成跑步這件事,最後他回報他跑了幾秒鐘;另一種結果是他拒絕跑步這件事,為什麼?他回報他就是不想跑步了。
我們將這整個過程寫成 Promise 物件來進行,可得以下的原始碼,首先,我們利用建構式建立一個 Promise 物件,並將此物件賦予給 running 這個變數,在 Promise 物件中引用 resolve
、reject
變數來做 fulfilled 或 rejected 狀態時的訊息(資料)傳遞,在此我們寫了隨機產生是否要跑步及跑步秒數的變數,帶入我們的 if…else 陳述式,當 run 為 true (確定跑步,fulfilled)時,則調用 resolve() 來傳遞跑了幾秒鐘,若是 run 為 false,則調用 reject() 來傳遞不想跑了。
1 | let running = new Promise((resolve, reject) => { |
最後,我們如何去執行這個物件來處理非同步與同步事件並接收訊息呢?
我們可以使用 then()
及 catch()
來接收,從範例中可以看到,當 Promise 中執行的條件有滿足時,我們在then()
傳入一個 function 並使用 data 變數來接收 fulfilled 狀態所傳遞的訊息,同樣的 rejected 狀態則是使用catch()
來接收。