Promise & Async:
異步處理的演進史
從混亂的 Callback Hell 到優雅的 Async/Await。徹底掌握 JavaScript 處理資料請求與長時間任務的終極方案。
痛點:歡迎來到「回呼地獄」
在 Promise 出現之前,我們要處理多個相依的非同步任務,程式碼會長得像這樣:
為什麼這很糟糕?
1. 難以閱讀與維護
程式碼不斷向右偏移,形成所謂的「金字塔」結構。
2. 錯誤處理極其困難
每一層都要寫一次 error callback,漏掉一個就導致整個程式崩潰。
一、Promise:一份未來的契約
Promise 本質上是一個「容器」,裡面存著某個未來才會結束的事件(通常是非同步操作)的結果。
Promise 狀態機演練
Pending (等候中)
Fulfilled (成功)
Rejected (失敗)
二、Promise Chaining:鏈結的力量
Promise 最強大的地方在於 `.then()` 會回傳一個新的 Promise,這讓我們可以把非同步操作「扁平化」。
錯誤處理的三個關鍵點
一網打盡
最後一個 .catch() 可以捕捉到鏈結中任何一個步驟拋出的錯誤。
斷點復原
你可以在鏈結中間插入 .catch(),回傳一個預設值,讓後續的 .then() 繼續跑。
Finally
無論成功或失敗,.finally() 都會執行,適合用來關閉 Loading 狀態。
三、進階技:並發處理與賽跑
當我們需要同時處理多個請求時,Promise 提供了幾個靜態方法。
Promise.all()
「全部都要成功才算成功。」
適合一次抓取多份相依資料,若有一個失敗則全部失敗。
Promise.race()
「誰跑最快就聽誰的。」
適合用來實作請求超時 (Timeout) 機制。
四、Async / Await:終極優雅
ES2017 推出的 `async/await` 讓我們能用同步的寫法處理非同步。它本質上是 Promise 的語法糖,讓程式碼更直覺、更好讀。
必須注意的細節:
Await 會暫停執行:在同一個函式內,await 之後的程式碼要等前面的跑完才會動。
Try...Catch:異步錯誤必須被捕捉,否則會導致 Unhandled Promise Rejection。
總結:踏上異步的大師之路
JavaScript 的異步處理從「回呼」進化到「契約 (Promise)」,最後到達了「同步化 (Async/Await)」。掌握這些工具,你就能在處理複雜的網路請求、檔案操作與定時任務時,保持程式碼的清晰與穩定。