function*
declaration (
function
keyword followed by an asterisk) defines a
generator 函数
, which returns a
Generator
对象。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
You can also define generator functions using the
GeneratorFunction
constructor, or the function expression syntax.
function* name([param[, param[, ... param]]]) {
statements
}
name
函数名称。
param
可选
The name of a formal parameter for the function.
statements
由函数本体组成的语句。
Generators are functions that can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.
Generators in JavaScript -- especially when combined with Promises -- are a very powerful tool for asynchronous programming as they mitigate -- if not entirely eliminate -- the problems with callbacks, such as Callback Hell and Inversion of Control . However, an even simpler solution to these problems can be achieved with async functions .
Calling a generator function does not execute its body immediately; an
iterator
object for the function is returned instead. When the iterator's
next()
method is called, the generator function's body is executed until the first
yield
expression, which specifies the value to be returned from the iterator or, with
yield*
, delegates to another generator function. The
next()
method returns an object with a
value
property containing the yielded value and a
done
property which indicates whether the generator has yielded its last value, as a boolean. Calling the
next()
method with an argument will resume the generator function execution, replacing the
yield
expression where an execution was paused with the argument from
next()
.
A
return
statement in a generator, when executed, will make the generator finish (i.e. the
done
property of the object returned by it will be set to
true
). If a value is returned, it will be set as the
value
property of the object returned by the generator.
Much like a
return
statement, an error is thrown inside the generator will make the generator finished -- unless caught within the generator's body.
When a generator is finished, subsequent
next()
calls will not execute any of that generator's code, they will just return an object of this form:
{value: undefined, done: true}
.
function* idMaker() {
var index = 0;
while (true)
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
// ...
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 }
const someObj = {
*generator () {
yield 'a';
yield 'b';
}
}
const gen = someObj.generator()
console.log(gen.next()); // { value: 'a', done: false }
console.log(gen.next()); // { value: 'b', done: false }
console.log(gen.next()); // { value: undefined, done: true }
class Foo {
*generator () {
yield 1;
yield 2;
yield 3;
}
}
const f = new Foo ();
const gen = f.generator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
class Foo {
*[Symbol.iterator] () {
yield 1;
yield 2;
}
}
const SomeObj = {
*[Symbol.iterator] () {
yield 'a';
yield 'b';
}
}
console.log(Array.from(new Foo)); // [ 1, 2 ]
console.log(Array.from(SomeObj)); // [ 'a', 'b' ]
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}
function* powers(n){
//endless loop to generate
for(let current =n;; current *= n){
yield current;
}
}
for(let power of powers(2)){
//controlling generator
if(power > 32) break;
console.log(power)
//2
//4
//8
//16
//32
}
| 规范 |
|---|
|
ECMAScript (ECMA-262)
The definition of 'function*' in that specification. |
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function*
|
Chrome 39 | Edge 13 | Firefox 26 | IE No | Opera 26 | Safari 10 | WebView Android 39 | Chrome Android 39 | Firefox Android 26 | Opera Android 26 | Safari iOS 10 | Samsung Internet Android 4.0 |
nodejs
4.0.0
|
IteratorResult
object instead of throwing
|
Chrome 49 | Edge 13 | Firefox 29 | IE No | Opera 36 | Safari 10 | WebView Android 49 | Chrome Android 49 | Firefox Android 29 | Opera Android 36 | Safari iOS 10 | Samsung Internet Android 5.0 | nodejs 6.0.0 |
Not constructable with
new
(ES2016)
|
Chrome 50 | Edge 13 | Firefox 43 | IE No | Opera 37 | Safari 10 | WebView Android 50 | Chrome Android 50 | Firefox Android 43 | Opera Android 37 | Safari iOS 10 | Samsung Internet Android 5.0 | nodejs 6.0.0 |
| Trailing comma in parameters | Chrome 58 | Edge 14 | Firefox 52 | IE No | Opera 45 | Safari 10 | WebView Android 58 | Chrome Android 58 | Firefox Android 52 | Opera Android 43 | Safari iOS 10 | Samsung Internet Android 7.0 | nodejs 8.0.0 |
完整支持
不支持
用户必须明确启用此特征。
function*
expression
GeneratorFunction
object
yield
yield*
Function
object
function
declaration
function
expression