async function*

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流瀏覽器均已支援。

async function* 宣告建立一個新的非同步生成器函式到給定名稱的繫結

你也可以使用 async function* 表示式定義非同步生成器函式。

試一試

async function* foo() {
  yield await Promise.resolve("a");
  yield await Promise.resolve("b");
  yield await Promise.resolve("c");
}

let str = "";

async function generate() {
  for await (const val of foo()) {
    str += val;
  }
  console.log(str);
}

generate();
// Expected output: "abc"

語法

js
async function* name(param0) {
  statements
}
async function* name(param0, param1) {
  statements
}
async function* name(param0, param1, /* …, */ paramN) {
  statements
}

注意:非同步生成器函式沒有對應的箭頭函式。

注意:function* 是獨立的分詞,所以它們可以被空白或行終止符分隔。然而,asyncfunction 之間不能有行終止符,否則會自動插入分號,導致 async 成為識別符號,其餘部分成為 function* 宣告。

引數

name

函式名稱。

param 可選

函式形式引數的名稱。有關引數的語法,請參閱函式參考

statements 可選

組成函式體的語句。

描述

async function* 宣告會建立一個 AsyncGeneratorFunction 物件。每次呼叫非同步生成器函式時,它都會返回一個新的 AsyncGenerator 物件,該物件符合非同步迭代器協議。每次呼叫 next() 都會返回一個 Promise,它解析為迭代器結果物件。

非同步生成器函式結合了非同步函式生成器函式的特性。你可以在函式體中使用 awaityield 關鍵字。這使你能夠透過 await 輕鬆處理非同步任務,同時利用生成器函式的惰性特性。

當一個 promise 從非同步生成器中 yield 出來時,迭代器結果 promise 的最終狀態將與 yield 出來的 promise 的狀態匹配。例如

js
async function* foo() {
  yield Promise.reject(new Error("failed"));
}

foo()
  .next()
  .catch((e) => console.error(e));

將記錄 Error: failed,因為如果 yield 出來的 promise 拒絕,迭代器結果也將拒絕。非同步生成器已解析結果的 value 屬性將不會是另一個 promise。

async function* 宣告的行為類似於function 宣告——它們被提升到其作用域的頂部,可以在其作用域中的任何位置呼叫,並且只能在特定上下文中重新宣告。

示例

宣告一個非同步生成器函式

非同步生成器函式總是產生結果的 promise——即使每個 yield 步驟都是同步的。

js
async function* myGenerator(step) {
  await new Promise((resolve) => setTimeout(resolve, 10));
  yield 0;
  yield step;
  yield step * 2;
}

const gen = myGenerator(2);
gen
  .next()
  .then((res) => {
    console.log(res); // { value: 0, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: 2, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: 4, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: undefined, done: true }
    return gen.next();
  });

使用非同步生成器函式讀取一系列檔案

在這個例子中,我們讀取了一系列檔案,並僅在請求時訪問其內容,使用 Node 的 fs/promises 模組。

js
async function* readFiles(directory) {
  const files = await fs.readdir(directory);
  for (const file of files) {
    const stats = await fs.stat(file);
    if (stats.isFile()) {
      yield {
        name: file,
        content: await fs.readFile(file, "utf8"),
      };
    }
  }
}

const files = readFiles(".");
console.log((await files.next()).value);
// Possible output: { name: 'file1.txt', content: '...' }
console.log((await files.next()).value);
// Possible output: { name: 'file2.txt', content: '...' }

規範

規範
ECMAScript® 2026 語言規範
# sec-async-generator-function-definitions

瀏覽器相容性

另見