試一試
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 |
瀏覽器相容性
載入中…