async function*

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

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 = 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 优雅的地处理异步任务,同时利用生成器函数的惰性。

当从异步生成器产生一个 promsie 时,迭代器结果 promise 的最终状态将与生成器产生的 promise 状态相同。例如:

js
async function* foo() {
  yield Promise.reject(1);
}

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

因为如果生成的 promise 被拒绝,迭代器的结果也将被拒绝,所以将输出 1。异步生成器兑现结果的 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);
// 可能的输出;{ name: 'file1.txt', content: '...' }
console.log((await files.next()).value);
// 可能的输出:{ name: 'file2.txt', content: '...' }

规范

Specification
ECMAScript® 2025 Language Specification
# sec-async-generator-function-definitions

浏览器兼容性

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
async function* statement

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

参见