Start · Sprachen · JavaScript · Referenz · Iterator.prototype[Symbol.dispose]()

Iterator.prototype[Symbol.dispose]()

Methode

Entsorgt einen Iterator, indem dessen <code>return()</code>-Methode aufgerufen wird. Damit lassen sich Iteratoren mit <code>using</code> automatisch schließen.

seit JavaScript ES2026 (Explicit Resource Management) – Chrome 134 Kategorie: method-property

Signatur

Iterator.prototype[Symbol.dispose]()

Beschreibung

Iterator.prototype[Symbol.dispose]() implementiert das Disposable-Protokoll für alle Iteratoren, die von Iterator.prototype erben. Das sind unter anderem Generator-Objekte, Array-, Map- und Set-Iteratoren sowie die Ergebnisse von Iterator-Helfern wie map() oder filter(). Die Methode prüft, ob der Iterator eine return()-Methode hat. Wenn ja, ruft sie diese ohne Argumente auf. Der Rückgabewert von return() wird verworfen.

Nützlich ist das, wenn du einen Iterator von Hand mit next() durchläufst und ihn vorzeitig verlassen willst. Eine for...of-Schleife ruft return() bei break, return oder einer Ausnahme schon von selbst auf. Bei manueller Steuerung musst du dich dagegen selbst darum kümmern. Mit using it = gen(); erledigt die Laufzeitumgebung das beim Verlassen des Blocks automatisch, auch wenn eine Ausnahme auftritt.

Bei Generatoren sorgt der Aufruf von return() dafür, dass offene finally-Blöcke laufen. So werden etwa Dateihandles, Sperren oder Verbindungen freigegeben. Iteratoren ohne eigene Aufräumlogik (z. B. Array-Iteratoren ohne return()) macht die Methode zu einem harmlosen Aufruf, der nichts bewirkt.

Rückgabewert

Typ
undefined
Beschreibung
Gibt immer undefined zurück. Das Ergebnis eines eventuellen return()-Aufrufs wird verworfen.

Beispiele

Generator mit using automatisch schließen

function* leseZeilen() {
  console.log('Ressource geöffnet');
  try {
    yield 'Zeile 1';
    yield 'Zeile 2';
    yield 'Zeile 3';
  } finally {
    console.log('Ressource geschlossen');
  }
}

{
  using zeilen = leseZeilen();
  console.log(zeilen.next().value);
  // Nur den Kopf lesen, dann Block verlassen
}
console.log('Nach dem Block');
Ressource geöffnet Zeile 1 Ressource geschlossen Nach dem Block

Manueller Aufruf von [Symbol.dispose]()

function* zaehler() {
  try {
    let i = 0;
    while (true) yield i++;
  } finally {
    console.log('Zähler beendet');
  }
}

const it = zaehler();
it.next();
it.next();
const ergebnis = it[Symbol.dispose]();
console.log(ergebnis);
console.log(it.next());
Zähler beendet undefined { value: undefined, done: true }

Eigener Iterator mit Aufräumlogik (Unterklasse von Iterator)

class Abfrage extends Iterator {
  #zeilen = ['Anna', 'Ben', 'Clara'];
  #index = 0;

  next() {
    return this.#index < this.#zeilen.length
      ? { value: this.#zeilen[this.#index++], done: false }
      : { value: undefined, done: true };
  }

  return() {
    console.log('Datenbank-Cursor freigegeben');
    return { value: undefined, done: true };
  }
}

const ersterTreffer = () => {
  using cursor = new Abfrage();
  return cursor.next().value;
};

console.log(ersterTreffer());
Datenbank-Cursor freigegeben Anna

Iterator-Helfer geben das Schließen weiter

function* quelle() {
  try {
    yield* [1, 2, 3, 4, 5];
  } finally {
    console.log('Quelle geschlossen');
  }
}

{
  using gerade = quelle().filter((n) => n % 2 === 0);
  console.log(gerade.next().value);
}
Quelle geschlossen 2

// Wichtig · Fallstricke

  • Kompatibilität: Die Methode gehört zum Vorschlag „Explicit Resource Management“ (using, Symbol.dispose, DisposableStack). Unterstützt wird sie in Chrome/Edge ab 134, Firefox ab 135 und Node.js ab 24. Safari unterstützt sie noch nicht. Für ältere Umgebungen brauchst du einen Transpiler (TypeScript 5.2+, Babel) und ein Polyfill (z. B. core-js).
  • Nicht gestartete Generatoren: Wurde next() noch nie aufgerufen, springt return() sofort in den Endzustand. Der Generator-Rumpf wurde nie betreten, darum läuft auch kein finally-Block. Aufräumcode steht also nur zur Verfügung, wenn der Generator schon läuft.
  • Bei for...of meist unnötig: for...of, Destrukturierung und Spread schließen Iteratoren beim vorzeitigen Abbruch schon von selbst. using lohnt sich vor allem bei manueller next()-Steuerung.
  • Kein Effekt ohne return(): Array-, Map-, Set- und String-Iteratoren haben keine return()-Methode. Der Aufruf ändert bei ihnen nichts, und der Iterator liefert danach weiter Werte.
  • Ausnahmen: Wirft return() einen Fehler, gibt [Symbol.dispose]() ihn weiter. Innerhalb von using kann dabei ein SuppressedError entstehen, wenn der Block schon mit einem Fehler verlassen wurde.
  • Asynchrone Iteratoren: Für Async-Generatoren gibt es stattdessen AsyncIterator.prototype[Symbol.asyncDispose](), das zusammen mit await using verwendet wird.