async function*
åºçº¿
广æ³å¯ç¨
èª 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 = str + val;
}
console.log(str);
}
generate();
// Expected output: "abc"
è¯æ³
async function* name(param0) {
statements
}
async function* name(param0, param1) {
statements
}
async function* name(param0, param1, /* â¦, */ paramN) {
statements
}
夿³¨ï¼ç®å¤´å½æ°ä¸è½ç¨æ¥å®ä¹å¼æ¥çæå¨å½æ°ã
夿³¨ï¼function å * æ¯ä¸¤ä¸ªåç¬çæ è®°ï¼å æ¤å®ä»¬å¯ä»¥ç¨ç©ºç½ææ¢è¡ç¬¦åéãç¶èï¼å¦æ async å function ä¹é´ææ¢è¡ç¬¦ï¼åä¼èªå¨æå
¥åå·ï¼å¯¼è´ async æä¸ºæ è¯ç¬¦ï¼èå
¶ä½å
容æä¸º function* 声æã
åæ°
name-
彿°åç§°ã
paramå¯é-
彿°çå½¢ååç§°ãæå ³åæ°çè¯æ³ï¼è¯·åé 彿°åèã
statementså¯é-
ææå½æ°ä½çè¯å¥ã
æè¿°
async function* 声æå建ä¸ä¸ª AsyncGeneratorFunction å¯¹è±¡ãæ¯æ¬¡è°ç¨å¼æ¥çæå¨å½æ°æ¶ï¼å®é½ä¼è¿åä¸ä¸ªæ°ç AsyncGenerator 对象ï¼è¯¥å¯¹è±¡ç¬¦å弿¥è¿ä»£å¨åè®®ãæ¯æ¬¡è°ç¨ next() é½ä¼è¿åä¸ä¸ª Promise 对象ï¼è¯¥å¯¹è±¡ä¼å
ç°ä¸ºè¿ä»£å¨ç»æå¯¹è±¡ã
弿¥çæå¨å½æ°å
¼å
·å¼æ¥å½æ°åçæå¨å½æ°çç¹æ§ãä½ å¯ä»¥å¨å½æ°ä½ä¸ä½¿ç¨ await å yield å
³é®åãè¿ä½¿ä½ è½å¤ä½¿ç¨ await ä¼é
çå°å¤ç弿¥ä»»å¡ï¼åæ¶å©ç¨çæå¨å½æ°çæ°æ§ã
å½ä»å¼æ¥çæå¨äº§çä¸ä¸ª promsie æ¶ï¼è¿ä»£å¨ç»æ promise çæç»ç¶æå°ä¸çæå¨äº§çç promise ç¶æç¸åãä¾å¦ï¼
async function* foo() {
yield Promise.reject(1);
}
foo()
.next()
.catch((e) => console.error(e));
å ä¸ºå¦æçæç promise 被æç»ï¼è¿ä»£å¨çç»æä¹å°è¢«æç»ï¼æä»¥å°è¾åº 1ã弿¥çæå¨å
ç°ç»æç value å°ä¸ä¼æ¯å¦ä¸ä¸ª promiseã
async function* 声æçè¡ä¸ºç±»ä¼¼äº function 声æï¼å®ä¼è¢«æåå°å
¶ä½ç¨åçé¡¶é¨ï¼å¹¶ä¸å¯ä»¥å¨å
¶ä½ç¨åçä»»ä½ä½ç½®è¢«è°ç¨ï¼å¹¶ä¸åªè½å¨å
¶ä»ä¸ä¸æä¸è¢«éæ°å£°æã
示ä¾
>声æå¼æ¥çæå¨å½æ°
弿¥çæå¨å½æ°æ»æ¯äº§çç»æ promiseââå³ä½¿æ¯ä¸ª yield æ¥éª¤æ¯åæ¥çã
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 模å读åä¸ç³»åæä»¶å¹¶ä¸ä»
å½è¯·æ±æ¶è·åå®çå
容ã
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: '...' }
è§è
| è§è |
|---|
| ECMAScript® 2027 Language Specification> # sec-async-generator-function-definitions> |