
Javascript: Callback, Promise, Async/Await
What is Callback?
Javascript 是一個 Asynchronous (非同步) 的語言。有 Asynchronous 當然也有 Synchronous, 它們之間的分別是:

Synchronous 是一個 function 接一個 function 來執行, 當前面的 function 未 return 後面的是不會執行的。
Asynchronous 則是不會等前面的 function return 而直接去執行下一個 function。 Javascript 就是這一種。
那麼如果 Javascript 想好像 Sync 一樣讓 functions 按著次序一個一個來執行, 應該怎樣?
這就是 Callback 登場的時候了。 Callback 的意思就像跟別人講電話說當你忙完你的事情請回我電話。在 Javascript如何實現呢?
這段code展示了一個簡單的 callback 的用法。我們希望先執行了 function a 再執行 function b 所以我們把 b 作為 a 的 argument 傳進去。但事情並不是這麼簡單,如果 b是一個需要等待的function。跟據JS的Asyn特性,它是不會等待的,因此之後的function會優先執行。
所以需要更多的callback function才能實現順序執行。
但是當程式越來越複雜,將需要更多的callback functions。這樣會產生一個問題 — Callback Hell !!

雖然在功能上,它可以滿足我們的要求,但是在閱讀性和維護性上則是大災難。
Promise!
它是ES6新增的功能,Promise並不為了解決 callback hell 而創造出來,而是提供另一個方法去解決 Javascript Async 的問題。當一個 Async 完成了的時候就會產生一個 Promise,這個 Promise會 return「成功」或者「失敗」給它的 Handler。而 return 的形式令 Async function 和 Sync function 更相似。
Promise 有三種 states:
Pending: operation 剛剛開始和正在執行中。
Fulfilled: operation 成功。
Rejected: operation 失敗。
How does Promise work?

.then(function(){…})是當Promise fulfill的時候出來接應的handler。
.catch(function(){…})是當Promise reject的時候出來接應的handler。
無論 .then() / .catch()都是 return Promise Object的,因此是可以不斷地 .then() / .catch()的。
new Promise((resolve, reject) => { do something })
這樣就創造了一個Promise Object,當成功時就使用resolve(…),而失敗時就使用reject(…)。
上面的例子展示了promise不同的用法和情況。首先我們有一個 function ‘output’ return 一個 promise object。內容很簡單就是等一秒之後如果有value就成功,沒有就失敗。Test1,傳一段string去output,它順利地使用resolve function和call了進入了then()。Test2,顯示如果失敗的情況和顯示有兩種寫法。
.then( success=>{...}, reject=>{...} );.then( success=>{...}).catch( reject=>{...} );
Test3,顯示如果我們在then(…)中return一個promise,我們是可以直接再使用then()去接的。
到了這裡,我們發現如果程式越趨複雜,promise hell 也是會出現的。為了有更好的閱讀性和維護性,async/await 出現了。
Async/Await
它們兩兄弟是 Syntactic Sugar,其令到 promise 更容易理解和使用。
Syntactic Sugar:有些 programming syntax 就像黑咖啡一般不是人人都容易入口,加一些糖 (Syntactic Sugar)令到咖啡更容易入口,而且糖是不會改變咖啡的結構的。
Async function 的工作只有一樣就是自動 return promise object。
async function test() {
return 1;
}
Await 只可以在 async function 內使用,它的工作是暫停 async function 內的其他function執行直到當下的 function 完成處理它的 promise 和 return 其結果。
var value = await promise;
以下我們會用例子去比較 promise 和 async/await 的寫法有甚麼不同。
對於一開始的 process() 來說,它加不加 async 其實分別不大,它都會return promise object。而對於 promise 和 async/await 的閱讀難度也不大分別。
那麼以下是一另個例子:
由此可見,當程式越來越複雜,可見 Async/Await 的寫法是更清楚的。
Conclusion
Callback, Promise, Async/Await 在寫法上是不同但它們的本質是一樣的,都為了在 Javascript 實現 Sync 的效果。