JavaScript 非同步與同步事件之 Promise
前言
async 與 await 是 JavaScript 中常見的東西,其中也與 Promise 也有關係,所以這邊也會先講一下 Promise 是什麼。
非同步與同步事件
首先到底非同步與同步事件是什麼東西呢?我們在 JavaScript 奇怪的部分有瞭解到 JavaScript 是單進程的程式語言(意旨一次只能做一件事情)
同步事件
舉例來講 JavaScript 就像下廚差不多,以同步 (async) 來講就像我要一定要先切菜 → 再切香菇 → 然後倒高湯 → 最後一定是上菜。
非同步事件
那非同步呢?做菜過程除了最後上菜之外,難道我們就一定要先切菜 → 再切香菇 → 然後倒高湯嗎?不一定,我們可以先切香菇或者先到高湯又或者在最後才切菜等等,簡單來說就是我們可以先做其他可以先做的事情,然後其他事情不會受到影響。
那剛剛前面有講到 JavaScript 是單進程程式語言,那他又是如何處理非同步事件的?在 JavaScript 中,他會先將應該要先處理的東西先處理完,然後再把需要做非同步處理的事情放進一個叫做事件佇(ㄓㄨˋ)列,又稱事件對列中,直到前面應該先處理完的事情處理完後再看事件佇列有什麼是準備要做的。
Promise
由於 JavaScript 中有非常多的非同步事件,所以就會有一個東西叫做 Callback Hell (回呼地獄),當我們希望這件事情可以處理之後在往下處理的時候就會這個恐怖的 Callback Hell。
那 Promise 該如何撰寫呢?
首先 Promise 是 ES6 新增的一個功能,所以必須使用函式來呼叫,常見的寫法就像這樣 ↓
1 | let newPromise = new Promise((resolve, reject) => { |
一開始我們無法知道哪一個函式會先被執行完,但是我們又希望他可以照順序來運作,那就可以這樣子寫 ↓
1 | let runPromiss = (name, time, status) => { |
從上面這個狀況下我們可以看到小明失敗之後直接回傳錯誤訊息。
可是如果今天小明是成功跑完,那接下來我們就可以看到接著換小王跑起來了。
小注意事項
所以我們就可以使用這種方式來處理非同步事件,這邊有一個事情一定要知道,如果 Promise 沒有回傳 resolve
,那就不會接下去 then
繼續運作唷,如下 ↓
1 | let runPromiss = (name, time, status) => { |
更多 Promise 介紹
因為 Prmoise 做法還滿多的,所以這邊提供還有那些文章。
重新認識 JavaScript: Day 26 同步與非同步
Callback Hell
順便科普 Callback Hell 會造成什麼影響。
剛剛前面有講到,當我們希望 JavaScript 在運作程式碼的時候,可以依照我們所希望的事件來依序處理,可是如果沒有使用 ES6 Promise 的時候,就很常會看到一推 if…if…判斷式來判斷資料是否已經正常取的或者處理完畢,當然我自己也有寫過這種 Callback Hell 在 debug 上是非常痛苦的,因為括號非常的多,會搞不清楚哪一個是哪一個的結尾區塊。
後來改用 Promise 之後就可以發現其實好 debug 多了(其實這部分還可以優化,最近有點忙)。