Skip to main content

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 鏈

  1. Generator 函數中,使用 yield 來產生一個 Promise 物件

  2. 一個外部的執行器 (Runner)(如 co 函式庫)會接收這個 Promise。

  3. Runner 負責等待 Promise 解決,然後將結果透過 .next(result) 傳回 Generator 內部,恢復執行,讓異步程式碼看起來像同步一樣。

這種模式雖然強大,但需要手動引入或編寫 Runner,增加了複雜性。


3. async/await:將 Generator 內建化 (現代實踐)

ES2017 引入的 async/await 就是將上述「Generator + Runner」的模式內建到 JavaScript 引擎中,成為更優雅、更專注於異步的語法糖。

Generator 模式 (手動)async/await 模式 (自動)核心功能
function*async function定義異步上下文,確保回傳 Promise。
yield Promiseawait暫停執行並等待 Promise 解決,引擎自動負責恢復和結果傳遞。
外部 RunnerJS 引擎自動驅動異步流程。

結論:為什麼現代程式碼更少直接使用 Generator 處理異步?

在現代 JavaScript 開發中,您通常只會直接學習 Promise (.then()) 作為基礎,然後直接跳到 async/await 作為實踐:

  • async/await 的語法更為直觀、清晰,是處理 Promise 異步流程的最佳標準

  • Generator 模式的異步用法已屬於過渡期的寫法,其功能已被語言本身所吸收和優化,故不再需要手動使用。

Generator Function 在其原本專長的領域(如惰性迭代)依然是不可或缺的利器。但在異步流程控制中,async/await 已成為絕對的主流。