Start · Sprachen · JavaScript · Referenz · AsyncIterator

AsyncIterator

Klasse

Basisklasse für asynchrone Iteratoren, die das <code>async iterator protocol</code> implementieren und über <code>for await...of</code> konsumiert werden können.

seit JavaScript ES2018 (async iteration); Helper-Klasse: ES2024 / Kategorie: core

Signatur

class AsyncIterator

Beschreibung

Ein AsyncIterator ist ein Objekt, das das asynchrone Iterator-Protokoll implementiert: Es besitzt eine next()-Methode, die ein Promise zurückgibt. Dieses Promise erfüllt sich mit einem Iterator-Resultat-Objekt der Form { value, done }. Solange done false ist, liefert value den nächsten Wert der Sequenz; ist done true, ist die Iteration abgeschlossen.

Asynchrone Iteratoren werden typischerweise mit for await...of konsumiert und eignen sich hervorragend für Datenströme, die zeitversetzt eintreffen – etwa Server-Sent Events, WebSocket-Nachrichten, Datei-Lesevorgänge in Node.js oder paginated API-Antworten. Ein Objekt gilt als async iterable, wenn es zusätzlich die Methode [Symbol.asyncIterator]() bereitstellt, die den Iterator selbst zurückgibt.

Seit ES2024 (Chrome 117+) existiert AsyncIterator als explizite eingebaute Klasse mit Hilfsmethoden wie map(), filter(), take(), drop(), flatMap(), reduce(), toArray() und forEach(). Diese ermöglichen eine deklarative Pipeline-Verarbeitung asynchroner Sequenzen, ohne alle Werte vorab materialisieren zu müssen.

Eigene asynchrone Iteratoren lassen sich am einfachsten mit einem async generator (async function*) erstellen, da JavaScript dann automatisch das korrekte Protokoll implementiert. Für Low-Level-Kontrolle kann man AsyncIterator.prototype direkt erweitern oder Klassen von AsyncIterator ableiten.

Rückgabewert

Typ
AsyncIterator
Beschreibung
AsyncIterator ist primär eine abstrakte Basisklasse und kein direkt instanziierbarer Konstruktor. Instanzen entstehen über async Generatoren oder eigene Implementierungen.

Beispiele

Async Generator als AsyncIterator konsumieren

// Async Generator erzeugt automatisch einen AsyncIterator
async function* fetchPages(baseUrl) {
  let page = 1;
  while (true) {
    const response = await fetch(`${baseUrl}?page=${page}`);
    if (!response.ok) break;
    const data = await response.json();
    if (data.items.length === 0) break;
    yield data.items;
    page++;
  }
}

// Konsumieren mit for await...of
const iterator = fetchPages('https://api.example.com/posts');
for await (const items of iterator) {
  console.log('Seite erhalten:', items.length, 'Einträge');
  if (items.length < 10) break; // letzte Seite
}
Seite erhalten: 10 Einträge Seite erhalten: 10 Einträge Seite erhalten: 7 Einträge

AsyncIterator-Hilfsmethoden (ES2024) als Pipeline

// Async Generator für einen Ereignisstrom simulieren
async function* eventStream() {
  const events = [
    { type: 'click', x: 10 },
    { type: 'move',  x: 20 },
    { type: 'click', x: 30 },
    { type: 'move',  x: 40 },
    { type: 'click', x: 50 },
  ];
  for (const e of events) {
    await new Promise(r => setTimeout(r, 50)); // simulierte Verzögerung
    yield e;
  }
}

// Pipeline: nur Klicks, erste 2, x-Koordinate extrahieren
const clicks = eventStream()
  .filter(e => e.type === 'click')
  .take(2)
  .map(e => e.x);

const result = await clicks.toArray();
console.log('Erste 2 Klick-X-Koordinaten:', result);
Erste 2 Klick-X-Koordinaten: [ 10, 30 ]

Eigenen AsyncIterator manuell implementieren

// Manuelle Implementierung des async iterator protocols
function createCountdown(from) {
  let current = from;
  return {
    // Macht das Objekt zum async iterable
    [Symbol.asyncIterator]() { return this; },

    async next() {
      if (current < 0) {
        return { value: undefined, done: true };
      }
      // Simulierte asynchrone Arbeit
      await new Promise(r => setTimeout(r, 100));
      return { value: current--, done: false };
    },

    async return(value) {
      console.log('Iterator vorzeitig beendet');
      current = -1;
      return { value, done: true };
    }
  };
}

for await (const n of createCountdown(3)) {
  console.log(n);
  if (n === 1) break; // löst return() aus
}
3 2 1 Iterator vorzeitig beendet

// Wichtig · Fallstricke

Browser-Kompatibilität: Das asynchrone Iterator-Protokoll (for await...of, async Generatoren) ist seit ES2018 breit unterstützt. Die eingebaute AsyncIterator-Klasse mit Hilfsmethoden (map, filter, take …) ist neuer (Chrome 117+, Firefox 131+, Safari 17.4+, Node.js 22+) und sollte in produktiven Umgebungen auf Verfügbarkeit geprüft werden.

Ressourcen-Management: Wird eine for await...of-Schleife vorzeitig durch break, return oder einen Fehler abgebrochen, ruft JavaScript automatisch die return()-Methode des Iterators auf. Eigene Iteratoren sollten diese implementieren, um Ressourcen (z. B. offene Verbindungen, Streams) sauber freizugeben.

Fehlerbehandlung: Wirft die next()-Methode oder ein yield im async Generator einen Fehler, wird das zurückgegebene Promise abgelehnt. In for await...of lässt sich das mit try...catch abfangen. Für explizite Fehlerinjektion kann die optionale throw()-Methode des Iterators genutzt werden.

Kein direkter Konstruktoraufruf: new AsyncIterator() erzeugt einen TypeError; die Klasse dient ausschließlich als Basisklasse zur Ableitung oder als Quelle für Prototype-Methoden.