Signatur
Beschreibung
Eine Generatorfunktion ist eine besondere Art von Funktion, die ihren Ausführungskontext zwischen mehreren Aufrufen einfriert und schrittweise Werte produziert. Sie wird mit dem Schlüsselwort function* (gesprochen: „function star") deklariert. Beim Aufruf führt sie den Funktionskörper nicht sofort aus, sondern gibt stattdessen ein Generator-Objekt zurück, das das Iterator- sowie das Iterable-Protokoll implementiert.
Innerhalb des Funktionskörpers steuert der yield-Ausdruck den Ablauf: Jedes Mal, wenn .next() auf dem Generator aufgerufen wird, läuft die Ausführung bis zum nächsten yield und pausiert dort. Der an yield übergebene Wert wird als value-Eigenschaft des Iteratorergebnisses zurückgegeben. Mit yield* kann die Ausführung an ein anderes Iterable delegiert werden.
- Lazy Evaluation: Werte werden erst bei Bedarf berechnet – ideal für potenziell unendliche Sequenzen.
- Bidirektionale Kommunikation:
.next(wert)kann einen Wert in den Generator hineinsenden, der dann als Ergebnis des pausiertenyield-Ausdrucks verfügbar ist. - Fehlerbehandlung: Mit
.throw(fehler)kann eine Ausnahme in den Generator geworfen und mittry/catchim Inneren abgefangen werden. Mit.return(wert)wird der Generator vorzeitig beendet.
Generatorfunktionen eignen sich besonders für benutzerdefinierte Iteratoren, asynchrone Ablaufsteuerung (vor async/await), unendliche Datenströme sowie für das Implementieren des [Symbol.iterator]-Protokolls in eigenen Klassen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | — | Der Name der Generatorfunktion. Wie bei normalen Funktionen ist der Name in der Deklarationsform erforderlich; bei Ausdrucksformen (const g = function* () {…}) kann er weggelassen werden. |
| $param1, param2, … | any | Beliebig viele formale Parameter, genau wie bei einer regulären Funktion. Rest-Parameter (...rest) und Standardwerte (param = default) sind erlaubt. |
Rückgabewert
Generator-Objekt, das gleichzeitig Iterator und Iterable ist. Es besitzt die Methoden .next(value), .return(value) und .throw(error).Beispiele
Einfache Zahlensequenz
function* zahlenBis(max) {
for (let i = 1; i <= max; i++) {
yield i;
}
}
const gen = zahlenBis(3);
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 }
// Auch per for-of nutzbar
for (const n of zahlenBis(5)) {
process.stdout.write(n + ' ');
}
// Ausgabe: 1 2 3 4 5
Unendlicher Fibonacci-Generator
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fib = fibonacci();
const erste8 = Array.from({ length: 8 }, () => fib.next().value);
console.log(erste8);
Bidirektionale Kommunikation mit .next(wert)
function* akkumulator() {
let summe = 0;
while (true) {
const eingabe = yield summe;
if (eingabe === null) break;
summe += eingabe;
}
return summe;
}
const acc = akkumulator();
acc.next(); // Generator starten (erster yield)
console.log(acc.next(10).value); // 10
console.log(acc.next(25).value); // 35
console.log(acc.next(5).value); // 40
console.log(acc.return()); // { value: 40, done: true }
yield* zur Delegation an ein anderes Iterable
function* buchstaben() {
yield* 'ABC';
}
function* kombiniert() {
yield 0;
yield* buchstaben();
yield 1;
}
console.log([...kombiniert()]);
// Wichtig · Fallstricke
Kein new: Generatorfunktionen können nicht mit new aufgerufen werden – das wirft einen TypeError.
Kein return als yield: Ein return wert-Statement innerhalb einer Generatorfunktion beendet den Generator und liefert { value: wert, done: true }. Dieser Wert wird von for-of und dem Spread-Operator ignoriert.
Pfeilfunktionen: Generatorfunktionen können nicht als Pfeilfunktion geschrieben werden (() => {} kennt kein *).
Async Generatoren: Ab ES2018 ist async function* verfügbar, das asynchrone Iteratoren erzeugt und mit for await...of konsumiert wird.
Browser-Kompatibilität: function* wird von allen modernen Browsern und Node.js ab Version 4 unterstützt (Baseline: alle modernen Browser).