Signatur
Beschreibung
Mit next() fordert man bei einem asynchronen Generator (definiert über async function*) den nächsten Wert an. Anders als beim synchronen Generator liefert die Methode nicht direkt ein Ergebnisobjekt, sondern ein Promise. Es wird mit einem Objekt der Form { value, done } erfüllt, sobald der Generator das nächste yield erreicht oder endet.
Das optionale Argument value wird im Generator zum Ergebnis des yield-Ausdrucks, an dem er zuvor angehalten hat. So kann der aufrufende Code Daten in den Generator zurückgeben, etwa für Steuerbefehle oder Rückmeldungen. Der Wert des ersten next()-Aufrufs wird verworfen, weil zu diesem Zeitpunkt noch kein yield erreicht wurde.
Meistens ruft man next() nicht selbst auf, sondern nutzt for await...of, das die Methode intern aufruft. Der direkte Aufruf ist sinnvoll, wenn man Werte gezielt einzeln abruft (z. B. „nächste Seite laden“), Werte in den Generator einspeist oder eigene Kombinatoren für Datenströme schreibt.
Aufrufe von next() werden intern in eine Warteschlange gestellt. Ruft man die Methode mehrmals auf, ohne auf das vorherige Promise zu warten, werden die Anfragen trotzdem der Reihe nach abgearbeitet. Die Ergebnisse kommen also nie in falscher Reihenfolge an.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value | any | undefined | Wert, der im Generator als Ergebnis des aktuell pausierten yield-Ausdrucks ankommt. Beim ersten Aufruf wird er ignoriert. |
Rückgabewert
Promise, das mit { value, done } erfüllt wird. Solange der Generator Werte liefert, ist done gleich false. Nach dem Ende ist done gleich true, und value enthält den return-Wert (sonst undefined). Wirft der Generator einen Fehler, wird das Promise mit diesem Fehler abgelehnt.Beispiele
Werte einzeln abrufen
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
async function* countdown(from) {
for (let i = from; i > 0; i--) {
await wait(100);
yield i;
}
return 'Start!';
}
const gen = countdown(3);
console.log(await gen.next());
console.log(await gen.next());
console.log(await gen.next());
console.log(await gen.next());
console.log(await gen.next());
Paginierte API bei Bedarf nachladen
async function* fetchPages(baseUrl) {
let page = 1;
while (true) {
const res = await fetch(`${baseUrl}?page=${page}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const items = await res.json();
if (items.length === 0) return;
yield items;
page++;
}
}
const pages = fetchPages('https://api.example.com/posts');
document.querySelector('#mehr').addEventListener('click', async () => {
try {
const { value, done } = await pages.next();
if (done) {
console.log('Keine weiteren Einträge.');
return;
}
console.log(`${value.length} Einträge geladen`);
} catch (err) {
console.error('Laden fehlgeschlagen:', err.message);
}
});
Werte per next(value) in den Generator senden
async function* akkumulator() {
let summe = 0;
while (true) {
const zahl = yield summe; // empfängt den Wert aus next()
summe += await Promise.resolve(zahl ?? 0);
}
}
const acc = akkumulator();
await acc.next(); // bis zum ersten yield laufen; Argument würde ignoriert
console.log((await acc.next(5)).value);
console.log((await acc.next(10)).value);
console.log((await acc.next(2)).value);
Parallele Aufrufe werden in der richtigen Reihenfolge abgearbeitet
async function* langsam() {
yield 'a';
await new Promise((r) => setTimeout(r, 200));
yield 'b';
yield 'c';
}
const g = langsam();
// Drei Anfragen gleichzeitig: Der Generator arbeitet sie nacheinander ab
const ergebnisse = await Promise.all([g.next(), g.next(), g.next(), g.next()]);
console.log(ergebnisse.map((r) => r.value));
// Wichtig · Fallstricke
- Immer mit
awaitauswerten:gen.next().doneistundefined, weilnext()ein Promise zurückgibt und kein Ergebnisobjekt. Richtig ist(await gen.next()).done. - Erster Wert wird verworfen: Das Argument des ersten
next()-Aufrufs kommt im Generator nie an. Werte für den Start übergibt man besser als Parameter der Generatorfunktion. - Fehler: Wirft der Generator einen Fehler, wird das Promise abgelehnt und der Generator gilt danach als beendet. Weitere Aufrufe liefern
{ value: undefined, done: true }. Unbehandelte Ablehnungen führen zuunhandledrejection-Warnungen, deshalbtry...catchverwenden. - Aufräumen: Wer
next()manuell aufruft und vorzeitig aufhört, solltereturn()aufrufen, damitfinally-Blöcke im Generator laufen (z. B. zum Schließen von Verbindungen).for await...oferledigt das beibreakautomatisch. yieldmit Promise: In asynchronen Generatoren wird ein mityieldübergebenes Promise automatisch aufgelöst.valueist also nie selbst ein Promise.- Kompatibilität: Seit ES2018 in allen modernen Browsern und in Node.js ab Version 10 verfügbar.
awaitauf oberster Ebene (wie in den Beispielen) funktioniert nur in ES-Modulen.