试一试
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
}
注意:异步生成器函数没有对应的箭头函数。
参数
name-
函数名称。
param可选-
函数形式参数的名称。有关参数的语法,请参阅函数参考。
statements可选-
组成函数体的语句。
描述
async function* 声明会创建一个 AsyncGeneratorFunction 对象。每次调用异步生成器函数时,它都会返回一个新的 AsyncGenerator 对象,该对象符合异步迭代器协议。每次调用 next() 都会返回一个 Promise,它解析为迭代器结果对象。
异步生成器函数结合了异步函数和生成器函数的特性。你可以在函数体中使用 await 和 yield 关键字。这使你能够通过 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 |
浏览器兼容性
加载中…