function*
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.
Die function*
-Deklaration erstellt eine Binding einer neuen Generatorfunktion mit einem gegebenen Namen. Eine Generatorfunktion kann beendet und später erneut aufgerufen werden, wobei ihr Kontext (variable Bindings) über verschiedene Aufrufe hinweg erhalten bleibt.
Generatorfunktionen können Sie auch mit dem function*
Ausdruck definieren.
Probieren Sie es aus
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
Syntax
function* name(param0) {
statements
}
function* name(param0, param1) {
statements
}
function* name(param0, param1, /* …, */ paramN) {
statements
}
Hinweis: Generatorfunktionen haben keine Gegenstücke als Pfeilfunktionen.
Hinweis:>function
und *
sind separate Tokens, sodass sie durch Leerzeichen oder Zeilenumbrüche getrennt werden können.
Parameter
name
-
Der Name der Funktion.
param
Optional-
Der Name eines formalen Parameters für die Funktion. Siehe die Funktionen-Referenz für die Syntax der Parameter.
statements
Optional-
Die Anweisungen, die den Körper der Funktion bilden.
Beschreibung
Eine function*
-Deklaration erstellt ein GeneratorFunction
-Objekt. Jedes Mal, wenn eine Generatorfunktion aufgerufen wird, gibt sie ein neues Generator
-Objekt zurück, das dem Iterator-Protokoll entspricht. Wenn die next()
-Methode des Iterators aufgerufen wird, wird der Körper der Generatorfunktion bis zum ersten yield
-Ausdruck ausgeführt, der den zurückzugebenden Wert des Iterators angibt oder, bei Verwendung von yield*
, an eine andere Generatorfunktion delegiert. Die next()
-Methode gibt ein Objekt mit einer value
-Eigenschaft, die den ausgegebenen Wert enthält, und einer done
-Eigenschaft zurück, die als boolescher Wert angibt, ob der Generator seinen letzten Wert ausgegeben hat. Wenn die next()
-Methode mit einem Argument aufgerufen wird, wird die Ausführung der Generatorfunktion fortgesetzt, wobei der yield
-Ausdruck, an dem die Ausführung angehalten wurde, durch das Argument von next()
ersetzt wird.
Generatoren in JavaScript — besonders in Kombination mit Promises — sind ein sehr mächtiges Werkzeug für asynchrone Programmierung, da sie die Probleme mit Callbacks, wie zum Beispiel Callback Hell und Inversion of Control, abschwächen — wenn nicht sogar vollständig beseitigen. Eine noch einfachere Lösung für diese Probleme kann jedoch mit async functions erreicht werden.
Eine return
-Anweisung in einem Generator beendet diesen, wenn sie ausgeführt wird (d.h. die done
-Eigenschaft des von ihm zurückgegebenen Objekts wird auf true
gesetzt). Wenn ein Wert zurückgegeben wird, wird er als value
-Eigenschaft des von dem Generator zurückgegebenen Objekts festgelegt. Ähnlich wie eine return
-Anweisung bewirkt ein innerhalb des Generators ausgelöster Fehler, dass der Generator beendet wird — es sei denn, er wird innerhalb des Generator-Körpers abgefangen. Wenn ein Generator beendet ist, führen nachfolgende next()
-Aufrufe keinen Code dieses Generators mehr aus; sie geben einfach ein Objekt dieser Form zurück: {value: undefined, done: true}
.
function*
-Deklarationen verhalten sich ähnlich wie function
-Deklarationen — sie werden gehoisted an den Anfang ihres Scopes und können überall in ihrem Scope aufgerufen werden, und sie können nur in gewissen Kontexten neu deklariert werden.
Beispiele
Grundlegendes Beispiel
function* idMaker() {
let index = 0;
while (true) {
yield index++;
}
}
const 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
// …
Beispiel mit yield*
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i) {
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
const 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
Übergabe von Argumenten an Generatoren
function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
const 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
Rückgabeanweisung in einem Generator
function* yieldAndReturn() {
yield "Y";
return "R";
yield "unreachable";
}
const 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 }
Generator als ein Objekt-Eigenschaft
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 }
Generator als Objektmethode
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 }
Generator als berechnete Eigenschaft
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' ]
Generatoren sind nicht konstruierbar
function* f() {}
const obj = new f(); // throws "TypeError: f is not a constructor
Generatorbeispiel
function* powers(n) {
// Endless loop to generate
for (let current = n; ; current *= n) {
yield current;
}
}
for (const power of powers(2)) {
// Controlling generator
if (power > 32) {
break;
}
console.log(power);
// 2
// 4
// 8
// 16
// 32
}
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification # sec-generator-function-definitions |
Browser-Kompatibilität
Siehe auch
- Funktionen Leitfaden
- Iteratoren und Generatoren Leitfaden
- Funktionen
GeneratorFunction
function*
Ausdruckfunction
async function
async function*
- Iterationsprotokolle
yield
yield*
Generator
- Regenerator auf GitHub
- Promises and Generators: control flow utopia Präsentation von Forbes Lindesay auf der JSConf (2013)
- Task.js auf GitHub
- You Don't Know JS: Async & Performance, Ch.4: Generators von Kyle Simpson