Signatur
Beschreibung
next() ist die zentrale Methode jedes Generator-Objekts. Bei jedem Aufruf läuft der Generator-Rumpf weiter, bis er auf den nächsten yield-Ausdruck, ein return oder das Ende der Funktion trifft. Zurück kommt ein Iterator-Ergebnisobjekt mit zwei Eigenschaften: value enthält den ausgegebenen Wert, done zeigt an, ob der Generator fertig ist.
Über den optionalen Parameter kann man einen Wert in den Generator hineinreichen: Er wird zum Ergebnis des yield-Ausdrucks, an dem der Generator gerade pausiert. Damit werden Generatoren zu Koroutinen, die in beide Richtungen kommunizieren. So funktionierten auch frühe Bibliotheken für asynchronen Ablauf (etwa co), bevor es async/await gab.
Meistens ruft man next() nicht selbst auf. for...of, der Spread-Operator, Array.from() und die Destrukturierung erledigen das im Hintergrund. Direkte Aufrufe braucht man, wenn man Werte an den Generator übergeben, gezielt einzelne Werte abrufen oder einen Zustandsautomaten Schritt für Schritt steuern will.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value | any | undefined | Wert, der an den Generator übergeben wird. Er wird zum Ergebnis des yield-Ausdrucks, an dem der Generator zuletzt angehalten hat. Beim ersten Aufruf von next() wird er ignoriert. |
Rückgabewert
done ist false, solange der Generator bei einem yield pausiert. Beim Abschluss wird es true, und value enthält dann den Wert aus return (sonst undefined).Beispiele
Grundlegender Ablauf von next()
function* ampel() {
yield 'rot';
yield 'gelb';
yield 'grün';
return 'aus';
}
const gen = ampel();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
Werte in den Generator hineinreichen (laufende Summe)
function* summierer() {
let summe = 0;
while (true) {
const zahl = yield summe; // erhält den Wert aus next(zahl)
summe += zahl;
}
}
const kasse = summierer();
kasse.next(); // Start: läuft bis zum ersten yield, Argument wird ignoriert
console.log(kasse.next(10).value);
console.log(kasse.next(5).value);
console.log(kasse.next(2.5).value);
ID-Generator: gezielt einzelne Werte abrufen
function* idGenerator(prefix = 'id') {
let n = 1;
while (true) yield `${prefix}-${n++}`;
}
const ids = idGenerator('user');
const neueNutzer = ['Anna', 'Ben'].map(name => ({ id: ids.next().value, name }));
console.log(neueNutzer);
Manuelle Iteration mit Abbruchbedingung
function* seiten() {
yield ['a', 'b'];
yield ['c'];
yield ['d', 'e'];
}
const it = seiten();
const gesammelt = [];
let ergebnis = it.next();
while (!ergebnis.done && gesammelt.length < 3) {
gesammelt.push(...ergebnis.value);
ergebnis = it.next();
}
console.log(gesammelt);
// Wichtig · Fallstricke
- Erster Aufruf: Das Argument des ersten
next()-Aufrufs geht verloren, weil noch keinyielddarauf wartet. Wer den Generator mit einem Anfangswert starten will, übergibt ihn als Parameter an die Generatorfunktion. - Der
return-Wert bleibt beifor...ofunsichtbar:for...of, Spread undArray.from()übergehen den Wert, bei demdone: trueist. Einen Rückgabewert perreturnsieht man nur bei manuellennext()-Aufrufen. - Ausnahmen: Wirft der Generator-Rumpf einen Fehler, gibt
next()ihn an den Aufrufer weiter. Danach ist der Generator beendet, und jeder weitere Aufruf liefert{ value: undefined, done: true }. - Wiedereintritt: Ruft man
next()innerhalb des laufenden Generators auf sich selbst auf, gibt es einenTypeError(„Generator is already running“). - Einmal verbraucht: Ein beendeter Generator lässt sich nicht zurücksetzen. Für einen neuen Durchlauf ruft man die Generatorfunktion erneut auf.
- Bei asynchronen Generatoren (
async function*) liefertnext()einPromiseauf das Ergebnisobjekt. - Kompatibilität: Alle modernen Browser und Node.js ab Version 4 unterstützen
next()(Baseline). Der Internet Explorer kann es nicht.