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 angegebenen Namen. Eine Generatorfunktion kann beendet und später erneut aufgerufen werden, wobei ihr Kontext (variable Bindings) über die erneuten Aufrufe hinweg gespeichert bleibt.
Sie können Generatorfunktionen auch mit dem function*
expression 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 in der Form von Pfeilfunktionen.
Hinweis: function
und *
sind separate Token, sodass sie durch Leerzeichen oder Zeilenumbrüche getrennt werden können.
Parameter
name
-
Der Name der Funktion.
param
Optional-
Der Name eines formalen Parameters der Funktion. Für die Syntax der Parameter siehe die Functions reference.
statements
Optional-
Die Anweisungen, die den Funktionskörper 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 Funktionskörper der Generatorfunktion bis zur ersten yield
-Anweisung ausgeführt, die den zurückzugebenden Wert aus dem Iterator angibt oder mit yield*
an eine andere Generatorfunktion delegiert. Die next()
-Methode gibt ein Objekt zurück, das eine value
-Eigenschaft mit dem gelieferten Wert und eine done
-Eigenschaft enthält, die als boolean angibt, ob der Generator seinen letzten Wert geliefert hat. Das Aufrufen der next()
-Methode mit einem Argument wird die Generatorfunktionsausführung wieder aufnehmen und dabei die yield
-Anweisung mit dem Argument von next()
ersetzen.
Generatoren in JavaScript — insbesondere in Kombination mit Promises — sind ein sehr leistungsstarkes Werkzeug für die asynchrone Programmierung, da sie die Probleme mit Rückrufen (Callbacks) verringern — wenn nicht sogar vollständig eliminieren — wie Callback Hell und Inversion of Control. Ein noch einfacherer Lösungsansatz für diese Probleme kann jedoch mit async functions erreicht werden.
Eine return
-Anweisung in einem Generator bewirkt, dass der Generator endet (d.h. die done
-Eigenschaft des zurückgegebenen Objekts wird auf true
gesetzt). Wenn ein Wert zurückgegeben wird, wird dieser als value
-Eigenschaft des vom Generator zurückgegebenen Objekts gesetzt. Ähnlich wie eine return
-Anweisung führt ein im Generator ausgelöster Fehler dazu, dass der Generator beendet wird — es sei denn, der Fehler wird im Körper des Generators abgefangen. Wenn ein Generator beendet ist, führen nachfolgende Aufrufe von next()
keinen Code des 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 an den Anfang ihres Gültigkeitsbereichs hoisted und können überall in ihrem Gültigkeitsbereich aufgerufen werden. Sie können nur in bestimmten Kontexten erneut deklariert werden.
Beispiele
Einfaches 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
Verwendung von return 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 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 Objekt-Methode
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
Generator, definiert in einer Ausdrucksweise
const foo = function* () {
yield 10;
yield 20;
};
const bar = foo();
console.log(bar.next()); // {value: 10, done: false}
Beispiel für einen Generator
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® 2025 Language Specification # sec-generator-function-definitions |
Browser-Kompatibilität
Report problems with this compatibility data on GitHubdesktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function* statement | ||||||||||||||
IteratorResult object instead of throwing | ||||||||||||||
Not constructable with new (ES2016) | ||||||||||||||
Trailing comma in parameters |
Legend
Tip: you can click/tap on a cell for more information.
- Full support
- Full support
Siehe auch
- Leitfaden zu Funktionen
- Iteratoren und Generatoren Leitfaden
- Funktionen
GeneratorFunction
function*
expressionfunction
async function
async function*
- Iterationsprotokolle
yield
yield*
Generator
- Regenerator auf GitHub
- Promises und Generatoren: Flusssteuerung Utopia, Vortrag von Forbes Lindesay bei JSConf (2013)
- Task.js auf GitHub
- You Don't Know JS: Async & Performance, Ch.4: Generators von Kyle Simpson