在一般「同步程式設計語言」中,程式碼執行的順序,就是一行一行跑下來,很容易理解
但 JavaScript 是「非同步程式設計語言」,很多時候,執行順序不是一行一行跑下來
為了讓用戶能持續流暢操作瀏覽器介面,工程師需要在會用到「非同步」的地方使用特殊寫法
最原始、也最單純的做法是使用 callback function,也就是把要在非同步任務結束後才跑的任務,寫在 callback function 傳進去
以 jquery 最原始的 ajax 處理為例
$.get(url, params, (data) => {
// do something with data
})
第三個參數,也就是箭頭函式的部份,就是所謂的 callback function
當年的前端工程師,在一開始覺得這樣寫沒問題,但是當網頁應用程式越來越複雜之後
發現在需要連續執行多個非同步任務時,會需要不斷傳 callback function 進去更深層
最後導致的結果,就是所謂的「callback hell」!這讓程式碼很難讀、很難維護!
$.get(url, params, (data) => {
// do something with data to get params2
$.get(url2, params2, (data) => {
// do something with data to get params3
$.get(url3, params3, (data) => {
// do the final task with data
});
});
});
這樣描述比較抽象,來跟著作業,試著用當年的方式開發看看吧!
讓我們時光倒轉,回到 2000 年代,體驗一下當時的開發方式
請使用 https://jsfiddle.net/ 寫作業
請載入 jquery 套件,並且用 jQuery.get()
來處理 ajax
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
假設你身為前端工程師,正在開發電商網站
今天,產品經理跟你說,為了提升 UX(用戶體驗)
希望能在網頁上顯示「最近一次的訂單內容」,就像這樣:
尊貴的客戶您好,您上次的消費內容是:
訂單編號:XXX
訂單內容:XXX
訂單金額:XXX
希望這次也能有機會服務您!
目前後端工程師提供了三組 API 給你使用
使用當年的 jquery 寫法會像是下面這樣:
為了簡化起見,你不用實作「登入、驗證」等等功能
就當作用戶已經登入了,請直接呼叫這個 API 即可
$.get("https://codelove.tw/fake-api/get-current-user", {}, (res) => {
console.log('the current user id is:' + res.data.user.id)
});
$.get("https://codelove.tw/fake-api/get-orders", { user_id: 1 }, (res) => {
console.log('get ' + res.data.orders.length + ' orders');
});
$.get("https://codelove.tw/fake-api/get-order-details", { order_id: 1 }, (res) => {
console.log('the order id is #' + res.data.order.id);
console.log('the order content is ' + res.data.order.content);
console.log('the order amount is $' + res.data.order.amount);
});
請注意,不要使用現代的非同步寫法,請使用 callback hell 的寫法,也就是:
寫完之後,你應該會看到有三層深度的巢狀 callback 傳遞!
這就有一點悲慘了,有點 callback hell 的感覺!
做出以上功能,你就完成這次的課程目標了!
歡迎將作業成果,在下方留言,跟大家分享,讓大家給你一些回饋!
可以將每課學到的觀念、關鍵字,丟到網路上去搜尋、研究一下!
發問請在「討論專區」為主,或者分享學習筆記、寫學習心得!
貼文都會出現在個人檔案頁面,成為學習歷程、部落格紀錄!
未來面試時,分享給面試官看,會讓人知道你的積極程度!
作業繳交
https://jsfiddle.net/jason60810/9zd0wpjL/11/
可以使用 array.at(-1).id 來取得最後一個 order 的 id
不用 array[ array.length - 1 ].id
作業繳交
https://jsfiddle.net/hung19091/ys42xpj1/2/
題外話:
之前為了寫Switch(模擬手把)的外掛
「等待N秒鐘」的功能是用await去實現
那個時候就寫過兩層的call back hell...(囧)
邁向資深之路:非同步 JS 訓練(一)—— 從 Callback Hell 到 Promise 介面
工作了很多年,還是搞不太懂 promise、async/await 是什麼嗎?用這份作業包一次搞定!
作業繳交
https://jsfiddle.net/gk5neq6z/54/