function*
Baseline
Widely available
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since 2016å¹´9æ.
function* 宣åå¼ï¼function ééµåå¾é¢è·èä¸åæèï¼å®ç¾©äºä¸åçæå¨å½å¼ï¼generator functionï¼ï¼ä»æåå³ä¸åçæå¨ï¼Generatorï¼ç©ä»¶ã
å試ä¸ä¸
function* generator(i) {
yield i;
yield i + 10;
}
const gen = generator(10);
console.log(gen.next().value);
// Expected output: 10
console.log(gen.next().value);
// Expected output: 20
ä½ å¯ä»¥éé GeneratorFunction 建æ§å¼ä¾å®ç¾©çæå¨å½å¼ã
èªæ³
function* name([param[, param[, ... param]]]) {
statements
}
name-
å½å¼å稱ã
param-
è¦è¢«å³å ¥å½å¼ç弿¸å稱ï¼ä¸åå½å¼æå¤å¯ä»¥ææ 255 å弿¸ã
statements-
statements æ§æäºå½å¼å §å®¹çé³è¿°å¼ã
æè¿°
çæå¨æ¯å¯ä»¥é¢éå¾å次é²å ¥çå½å¼ãå¨å ©æ¬¡é²å ¥ä¹éï¼çæå¨çå·è¡çæ ï¼è®æ¸ç¶å®çæ ï¼æè¢«å²åã
å¼å«çæå¨å½å¼ä¸¦ä¸æè®è£¡é¢çç¨å¼ç¢¼ç«å³å·è¡ï¼èæ¯æåå³ä¸åéå°è©²å½å¼çè¿ä»£å¨ï¼iteratorï¼ç©ä»¶ãç¶å¼å«è¿ä»£å¨ç next() æ¹æ³æï¼çæå¨å½å¼å°æå·è¡å°ééç第ä¸å yield éç®å¼ï¼è©²éç®å¼çµ¦å®çå¼å°å¾è¿ä»£å¨ä¸åå³ï¼å¦ææ¯ yield* åæäº¤çµ¦å¦ä¸åçæå¨å½å¼èçãnext() æ¹æ³åå³ä¸åç©ä»¶ï¼è©²ç©ä»¶æ value 屬æ§ï¼å
å«äºç¢ççæ¸å¼ï¼éæ done 屬æ§ï¼çºå¸æå¼ï¼æåºè©²çæå¨æ¯å¦ç¢åºæå¾çæ¸å¼ãå¼å« next() æ¹æ³å¦æå¸¶æä¸å忏ï¼å°æè®å
åæ«åççæå¨å½å¼æ¢å¾©å·è¡ï¼ä»¥è©²åæ¸å¼å代å
åæ«åç yield é³è¿°å¼ã
çæå¨ä¸ç return é³è¿°å¼è¢«å·è¡æï¼æè®çæå¨ done çæ
çºçãè¥ææ¸å¼è¢«è¿åçåä½å¸¶åï¼å°æ¯æ¾å¨ value å³åçãå·²è¿åççæå¨ä¸æåç¢ç任使¸å¼ã
ç¯ä¾
>ç°¡å®ä¾å
function* idMaker() {
var index = 0;
while (index < index + 1) yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// ...
yield* çç¯ä¾
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i) {
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
var gen = generator(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
å³å ¥å¼æ¸è³çæå¨
function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next(); // 0
gen.next("pretzel"); // 1 pretzel
gen.next("california"); // 2 california
gen.next("mayonnaise"); // 3 mayonnaise
çæå¨ä¸çåå³é³è¿°å¼
function* yieldAndReturn() {
yield "Y";
return "R";
yield "unreachable";
}
var gen = yieldAndReturn();
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }
çæå¨ç¡æ³è¢«å»ºæ§
function* f() {}
var obj = new f(); // throws "TypeError: f is not a constructor"
以表éå¼å®ç¾©çæå¨
const foo = function* () { yield 10; yield 20; };
const bar = foo();console.log(bar.next()); // {value: 10, done: false}
è¦ç¯
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-generator-function-definitions> |
ç覽å¨ç¸å®¹æ§
Firefox è¦ç¯è¨»è¨
Generators and iterators in Firefox versions before 26
Older Firefox versions implement an older version of the generators proposal. In the older version, generators were defined using a regular function keyword (without an asterisk) among other differences. See Legacy generator function for further information.
IteratorResult object returned instead of throwing
Starting with Gecko 29, the completed generator function no longer throws a TypeError "generator has already finished". Instead, it returns an IteratorResult object like { value: undefined, done: true } (Firefox bug 958951).
åè¦
function* expressionGeneratorFunctionobject- è¿ä»£åè°
yieldyield*Functionobjectfunction declarationfunction expressionFunctions and function scope- Other web resources:
- Regenerator an ES2015 generator compiler to ES5
- Forbes Lindesay: Promises and Generators: control flow utopia â JSConf EU 2013
- Task.js
- Iterating generators asynchronously