Start · Sprachen · JavaScript · Referenz · new DisposableStack()

new DisposableStack()

Methode

Der Konstruktor <code>DisposableStack()</code> erzeugt einen leeren Stapel, der mehrere Aufräumaktionen sammelt und sie beim Freigeben in umgekehrter Reihenfolge ausführt.

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

Signatur

new DisposableStack()

Beschreibung

Mit new DisposableStack() erzeugst du ein leeres DisposableStack-Objekt. Darin sammelst du Ressourcen und Aufräumfunktionen, die später gemeinsam freigegeben werden sollen, zum Beispiel Dateihandles, Sperren, Event-Listener oder Timer. Beim Aufruf von dispose() oder am Ende eines using-Blocks laufen alle registrierten Aufräumaktionen in umgekehrter Reihenfolge ab (LIFO, zuletzt hinzugefügt wird zuerst aufgeräumt).

Registriert wird über drei Methoden: use(value) für Objekte mit einer [Symbol.dispose]()-Methode, adopt(value, onDispose) für Werte ohne eigene Freigabelogik und defer(onDispose) für eine reine Aufräumfunktion. Mit move() überträgst du alle Einträge auf einen neuen Stapel. Das ist praktisch, wenn ein Konstruktor oder eine Fabrikfunktion Ressourcen erst dann an den Aufrufer übergeben soll, wenn alles geklappt hat.

Der Konstruktor erwartet keine Argumente und muss mit new aufgerufen werden. Weil DisposableStack selbst [Symbol.dispose] implementiert, lässt er sich direkt mit using deklarieren: using stack = new DisposableStack();. Für asynchrone Aufräumarbeiten gibt es das Gegenstück AsyncDisposableStack.

Rückgabewert

Typ
DisposableStack
Beschreibung
Ein neues, leeres DisposableStack-Objekt, dessen disposed-Eigenschaft false ist.

Beispiele

Stapel erzeugen und manuell freigeben

const stack = new DisposableStack();

stack.defer(() => console.log('Aufräumen: Verbindung schließen'));
stack.defer(() => console.log('Aufräumen: Cache leeren'));

console.log(stack.disposed);
stack.dispose();
console.log(stack.disposed);
false Aufräumen: Cache leeren Aufräumen: Verbindung schließen true

Mit using automatisch aufräumen

const createTimer = (label) => {
  const id = setInterval(() => {}, 1000);
  console.log(`${label} gestartet`);
  return { id, [Symbol.dispose]() { clearInterval(id); console.log(`${label} gestoppt`); } };
};

function runJob() {
  using stack = new DisposableStack();
  stack.use(createTimer('Timer A'));
  stack.use(createTimer('Timer B'));
  // adopt: Wert ohne eigenes Symbol.dispose
  const controller = stack.adopt(new AbortController(), (c) => {
    c.abort();
    console.log('Controller abgebrochen');
  });
  console.log('Job läuft, Signal aktiv:', !controller.signal.aborted);
} // hier wird der Stapel automatisch freigegeben

runJob();
Timer A gestartet Timer B gestartet Job läuft, Signal aktiv: true Controller abgebrochen Timer B gestoppt Timer A gestoppt

Ressourcen sicher übergeben mit move()

class Connection {
  #stack;
  constructor() {
    using stack = new DisposableStack();
    stack.defer(() => console.log('Socket geschlossen'));
    stack.defer(() => console.log('Log-Datei geschlossen'));
    // Schlägt hier etwas fehl, räumt using sofort alles auf.
    // Klappt alles, übernimmt die Instanz die Ressourcen:
    this.#stack = stack.move();
  }
  [Symbol.dispose]() {
    this.#stack.dispose();
  }
}

{
  using conn = new Connection();
  console.log('Verbindung in Benutzung');
}
Verbindung in Benutzung Log-Datei geschlossen Socket geschlossen

// Wichtig · Fallstricke

  • Kompatibilität: Das Feature ist neu (Explicit Resource Management, ES2026). Chrome/Edge 134+, Firefox 134+ und Node.js 24+ unterstützen es, Safari noch nicht. Bei älteren Umgebungen hilft ein Polyfill (z. B. core-js). Die using-Syntax braucht zusätzlich Unterstützung durch Engine oder Transpiler (TypeScript 5.2+, Babel).
  • Ohne new aufgerufen wirft DisposableStack() einen TypeError.
  • Nach dispose() oder move() ist der Stapel verbraucht. Weitere Aufrufe von use(), adopt(), defer() oder move() werfen einen ReferenceError. Ein erneutes dispose() bewirkt nichts.
  • Werfen mehrere Aufräumfunktionen Fehler, werden sie in einem SuppressedError verschachtelt. Die übrigen Aufräumaktionen laufen trotzdem weiter.
  • use() akzeptiert null und undefined (sie werden ignoriert). Andere Werte ohne [Symbol.dispose] führen zu einem TypeError.
  • Für Promise-basierte Aufräumarbeiten gibt es AsyncDisposableStack zusammen mit await using. DisposableStack wartet nicht auf zurückgegebene Promises.