告別 Promise 迎接 Async/Await 
先說 promise 在很久以前,那是個 JavaScript callback hell 的年代,為了處理這種處境,有人提出了 Promise 的寫法。而 Promise 也是近年開發 JavaScript 程式不可或缺的一門基礎,在 ES2015 也將 Promise 納為其中的一項標準。
非同步 function 關於非同步的文章網路上已經很多了,就不在此贅述。在這裡我直接先以 Promise 實作一個簡易的非同步程式:
promise 1 2 3 4 5 6 7 8 9 10 11 const  fetch = require ('node-fetch' )function  fetchCat  (userId )  {    return  fetch(`https://catappapi.herokuapp.com/users/${userId} ` )         .then(response  =>  respone.json())         .then(data  =>  data.imageUrl) } const  result = fetchCat (123 )console .log(result)
 
如果是 Async/Await? 換成 Async/Await 的話,就不必寫下 .then() 了!就像同步的程式一般,不必理會它是否為非同步。
1 2 3 4 5 6 7 8 9 10 11 const  fetch = require ('node-fetch' )async  function  fetchCat  (userId )  {    const  response = await  fetch(`https://catappapi.herokuapp.com/users/${userId} ` )     const  data = await  response.json()     return  data.imageUrl } const  result = fetchCat (123 )console .log(result)
 
宣告在 function fetchCat 的 async 表示該 function 是個非同步的。而在 function 內 response與data 之前的 await 表示要等待這個非同步的結果回傳後才會繼續執行,也就是說這個 function 內的程式都變為同步了!
進階點 先看這句話
Inside a function marked as asucn, you are allowed to place the await keyword in front of an expression taht returns a prmise. When you do, the execution of the async function is paused until the promise is resoled.
– MPJ 
 
會發現其實Async/Await 是基於 promise 所完成的。
連續.then() 改成 Async/Await promise 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const  fetch = require ('node-fetch' )function  fetchCat  (userId )  {    return  fetch(`https://catappapi.herokuapp.com/users/${userId} ` )         .then(response  =>  respone.json())         .then(user  =>  {             const  promises = user.cats.map(catId  =>                   fetch(`https://catappapi.herokuapp.com/cats/${catId} ` )                     .then(response  =>  response.json())                     .then(catData  =>  catData.imageUrl)             )             return  Promise .all(promises)         }) } const  result = fetchCat (123 )console .log(result)
 
Async/Await 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const  fetch = require ('node-fetch' )async  function  fetchCat  (userId )  {    const  resp = await  fetch(`https://catappapi.herokuapp.com/users/${userId} ` )     const  user = resp.json()     const  catImageUrls =[]     for  (const  catId of  user.cats){         const  resp = await  fetch(`https://catappapi.herokuapp.com/cats/${catId} ` )         const  catData = await  resp.json()         catImageUrls.push(catData.umageUrl)     }     return  catImageUrls } const  result = fetchCat (123 )console .log(result)
 
如果這樣你覺得不夠簡潔可以搭配 Promise.all做出reurn更簡潔的寫法取帶同步迴圈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const  fetch = require ('node-fetch' )async  function  fetchCat  (userId )  {    const  resp = await  fetch(`https://catappapi.herokuapp.com/users/${userId} ` )     const  user = resp.json()          return  await  Promise .all(user.cats.map(async  function  (catId )  {         const  resp = await  fetch(`https://catappapi.herokuapp.com/cats/${catId} ` )         const  catData = await  resp.json()         return  catData.imageUrl     })) } const  result = fetchCat (123 )console .log(result)
 
總結 async/await 的貢獻在語法上為 Javascripte 進行大優化,原本執行多行 Promises 程式簡化成一行,不僅僅提高程式的可讀性,也是為 functional programming 量身訂造的設計。
- PS 缺少 `` Error handle`` 待補