課程目標

  • 認識 async/await 語法

課程內容

體驗過 promise 之後,你會發現雖然改善很多,但還是有一點點麻煩

因為你需要 .then() 還有 return,而且,還是有一層巢狀結構

因此,工程師在 ES2017 又提出了一個解決辦法,叫做 async/await

因為 async/await 只是 promise 的另一種語法,背後一模一樣,所以繼續拿 jquery 當範例看看

原本的串接

$.get(url, params).then((data) => {
  // do something with data to get params2

  return $.get(url2, params2);
}).then((data) => {
  // do something with data to get params3

  return $.get(url3, params3);
}).then((data) => {
  // do the final task with data
});

可以用 async/await 改寫成

const data1 = await $.get(url, params);

// do something with data to get params2

const data2 = await $.get(url2, params2);

// do something with data to get params3

const data3 = await $.get(url3, params3);

// do the final task with data

神奇吧?看起來跟一般的同步程式設計,幾乎一模一樣了!

這邊要知道的是,await 後面的內容,其實就是 .then() 裡面 return 回傳的內容

只是寫法不同,其實背後是完全一樣的東西!


這句話很重要,再看一次!未來只要有點迷惘,就用這句話再思考一次:

你每次只要看到 await,就要去想「現在是去剝開 promise 的 then 裡面,拿出最後回傳的內容!」

有點看不懂沒關係,就先跟著使用方式,照做即可!

工作上多用幾次之後,會逐漸抓到感覺!

就先跟著作業,試著使用看看 async/await 吧!


你可能會問:那 async 是什麼時候用?

在 JS 環境中,有些時候,可以直接寫 await

有些時候,會跳警告,要求必須要使用 async 關鍵字包裝過,才能使用 await

僅此而已,暫時分不清 async 關鍵字使用時機,沒關係,遇到警告錯誤,再補上就可以了

最簡單的做法,你就把整段程式碼,放進一個隨便命名的 main 函式裡面,加上 async 關鍵字,然後執行 main

const main = async () => {
  // move your code to here
}

main();

老話一句,工作上多用幾次之後,會逐漸抓到感覺!

課後作業

在前一課的作業中,你稍微體驗到 2015 年代,前端工程師使用的「Promise Chain 鏈接」寫法

在這一課的作業,我們將時間快轉到 2017 年代,體驗一下所謂 async/await 是什麼


jquery 有支援 promise 介面,所以當然可以直接用 async/await

原本的 .then() 寫法

$.get(url, params).then(callback)

可以改寫為

const data = await $.get(url, params)

請將上一課的作業,使用 async/await 改寫

寫完之後,你應該會看到多個 await 出現,並且整段程式碼看起來很像「一般程式語言中,同步程式設計」的寫法!

而且,完全沒有 callback function 的傳遞!

做出以上功能,你就完成這次的課程目標了!

⚠️特別注意事項:請耐心 debug!⚠️

請注意,跟上一課一樣,由於本課簡化內容,沒有寫錯誤處理,錯誤訊息可能不會顯示!

請用 console.log 慢慢查看每行程式碼的執行結果,慢慢寫出這一課作業!


歡迎將作業成果,在下方留言,跟大家分享,讓大家給你一些回饋!

可以將每課學到的觀念、關鍵字,丟到網路上去搜尋、研究一下!

發問請在「討論專區」為主,或者分享學習筆記、寫學習心得!

貼文都會出現在個人檔案頁面,成為學習歷程、部落格紀錄!

未來面試時,分享給面試官看,會讓人知道你的積極程度!


共有 8 則留言

作業繳交 https://jsfiddle.net/gk5neq6z/102/ 有個地方我不是很懂,我不知道應不應該加上 await。

const userData = await $.get(getUserAPI)
const userId = (這裡需不需要加上 await) userData.data.user.id
按讚的人:

寫得很好,順利完成!


回答你的問題:不需要

因為 userData 已經是一個單純的 json 物件,一般使用即可

會需要 await 的東西,只要用 console.log 去看,都會發現是 Promise 型別


用本課教的心法,再思考一次:

你每次只要看到 await,就要去想「現在是去剝開 promise 的 then 裡面,拿出最後回傳的內容!」

$.get 那邊,是 ajax,是非同步處理,所以需要去「剝開 promise 的 then 裡面,拿出最後回傳的內容」

userData 那邊,就只是普通的物件取值,不需要「特別剝開」

按讚的人:

原來如此,我原本想的是需不需要等到 userData 回來才能取到 userId,所以才會想是否需要加上 await。 感謝站長的解惑!

按讚的人:

作業繳交 https://jsfiddle.net/jason60810/gwdn7c6f/6/

  1. try/catch:在使用async和await時,我們使用try/catch來進行錯誤處理。如果API請求或其他操作出錯,程式會立即跳到catch區塊。

  2. finally:這部分用來更新UI,不論之前的操作成功或失敗,它都會執行。

  3. async function 回傳 Promise:使用async宣告的函數會自動回傳一個Promise。即使函數內沒有明確返回值(return),它仍然會回傳一個解析為undefined的Promise,所以可以在函數執行完畢後使用.then()或await進行後續操作,如下:

fetchOrderDetails().then(() => {
  console.log("fetchOrderDetails has completed.");
});
按讚的人:

寫得很好,順利完成! 感謝補充資訊!

作業繳交 https://jsfiddle.net/hung19091/j0oqvgc8/12/

傳參數的部分,如果傳入參數名稱,跟自己宣告的變數名稱相符 可使用語法糖 例如: { user_id: user_id } 省略為: { user_id }

按讚的人:

寫得很好,順利完成! 感謝補充資訊!

交作業 https://jsfiddle.net/birdie2019/ydzsu43c/24/

按讚的人:
免費

邁向資深之路:非同步 JS 訓練(一)—— 從 Callback Hell 到 Promise 介面

工作了很多年,還是搞不太懂 promise、async/await 是什麼嗎?用這份作業包一次搞定!


👉 身份:資深全端工程師、指導過無數人半路出家轉職 👉 使命:打造 CodeLove 成為優質新手村,讓非本科也有地方自學&討論