JavaScript 生成器函數 (Generator) 與 async/await
Generator Function 是什麼?
Generator function(生成器函數)是一種特殊的 JavaScript 函數,使用 function* 宣告。它最核心的特點是能夠暫停執行並保存狀態,然後在需要時透過呼叫其回傳的 Generator 物件的 .next() 方法來恢復執行。
-
暫停點: 函數使用
yield關鍵字來暫停並產生一個值。 -
用途: Generator 常被用於處理惰性求值(Lazy Evaluation)、無限序列或建立客製化迭代器。
Generator 與異步程式設計的關係
Generator Function 是 async/await 語法糖的底層基礎,這段歷史體現了 JavaScript 異步控制流的演進。
1. Promise:異步的標準容器 (基礎)
在 Generator 之前,Promise(承諾)是解決傳統回呼地獄(Callback Hell)的標準方案。Promise 提供了 .then() 和 .catch() 來處理未來的值和錯誤,這是異步操作的核心容器。
2. Generator 模式:Promise 的「手動」執行器 (過渡期)
在 async/await 正式出現前,開發者發現可以利用 Generator 的暫停特性來簡化複雜的 Promise 鏈:
-
Generator 函數中,使用
yield來產生一個 Promise 物件。 -
一個外部的執行器 (Runner)(如
co函式庫)會接收這個 Promise。 -
Runner 負責等待 Promise 解決,然後將結果透過
.next(result)傳回 Generator 內部,恢復執行,讓異步程式碼看起來像同步一樣。
這種模式雖然強大,但需要手動引入或編寫 Runner,增加了複雜性。
3. async/await:將 Generator 內建化 (現代實踐)
ES2017 引入的 async/await 就是將上述「Generator + Runner」的模式內建到 JavaScript 引擎中,成為更優雅、更專注於異步的語法糖。
| Generator 模式 (手動) | async/await 模式 (自動) | 核心功能 |
|---|---|---|
function* | async function | 定義異步上下文,確保回傳 Promise。 |
yield Promise | await | 暫停執行並等待 Promise 解決,引擎自動負責恢復和結果傳遞。 |
| 外部 Runner | JS 引擎 | 自動驅動異步流程。 |
結論:為什麼現代程式碼更少直接使用 Generator 處理異步?
在現代 JavaScript 開發中,您通常只會直接學習 Promise (.then()) 作為基礎,然後直接跳到 async/await 作為實踐:
-
async/await的語法更為直觀、清晰,是處理 Promise 異步流程的最佳標準。 -
Generator 模式的異步用法已屬於過渡期的寫法,其功能已被語言本身所吸收和優化,故不再需要手動使用。
Generator Function 在其原本專長的領域(如惰性迭代)依然是不可或缺的利器。但在異步流程控制中,async/await 已成為絕對的主流。