Start · Sprachen · JavaScript · Referenz · AsyncDisposableStack.prototype[Symbol.asyncDispose]()

AsyncDisposableStack.prototype[Symbol.asyncDispose]()

Methode

Entsorgt asynchron alle im <code>AsyncDisposableStack</code> registrierten Ressourcen in umgekehrter Reihenfolge; wird von <code>await using</code> automatisch aufgerufen.

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

Signatur

AsyncDisposableStack.prototype[Symbol.asyncDispose]()

Beschreibung

Die Methode [Symbol.asyncDispose]() implementiert das asynchrone Entsorgungsprotokoll für AsyncDisposableStack-Instanzen. Deshalb lässt sich ein Stack direkt mit await using deklarieren: Verlässt der Programmfluss den umgebenden Block (normal, durch return oder durch eine Ausnahme), ruft die Laufzeit automatisch stack[Symbol.asyncDispose]() auf und wartet auf das zurückgegebene Promise.

Diese Methode ist dasselbe Funktionsobjekt wie AsyncDisposableStack.prototype.disposeAsync(). Sie arbeitet alle über use(), adopt() und defer() registrierten Aufräumaktionen in umgekehrter Registrierungsreihenfolge (LIFO) ab und wartet jede einzelne ab, bevor die nächste startet. So werden abhängige Ressourcen in der richtigen Reihenfolge geschlossen, z. B. erst eine Transaktion, dann die Datenbankverbindung.

Werfen eine oder mehrere Aufräumaktionen einen Fehler, laufen die übrigen trotzdem weiter. Am Ende wird das Promise mit dem Fehler abgelehnt. Bei mehreren Fehlern werden sie in SuppressedError-Objekten verschachtelt. Nach dem Aufruf ist stack.disposed gleich true. Weitere Aufrufe bewirken nichts und liefern ein erfülltes Promise.

Direkt aufrufen muss man die Methode nur selten. Meist nutzt man await using oder, für bessere Lesbarkeit, den Alias disposeAsync(). Nützlich ist der direkte Zugriff zum Beispiel, wenn eine eigene Klasse ihren internen Stack in ihrer eigenen [Symbol.asyncDispose]()-Methode weiterreicht.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das mit undefined erfüllt wird, sobald alle Aufräumaktionen abgeschlossen sind. Es wird abgelehnt, wenn mindestens eine Aufräumaktion einen Fehler geworfen hat; mehrere Fehler werden als SuppressedError verschachtelt.

Beispiele

Automatische Entsorgung mit await using (LIFO-Reihenfolge)

// Als ES-Modul ausführen (Top-Level-await)
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function verarbeiteAuftrag() {
  await using stack = new AsyncDisposableStack();

  stack.defer(async () => {
    await sleep(10);
    console.log("Datenbankverbindung geschlossen");
  });
  stack.defer(async () => {
    await sleep(10);
    console.log("Temporäre Datei gelöscht");
  });

  console.log("Auftrag verarbeitet");
  // Beim Verlassen des Blocks: await stack[Symbol.asyncDispose]()
}

await verarbeiteAuftrag();
Auftrag verarbeitet Temporäre Datei gelöscht Datenbankverbindung geschlossen

Direkter Aufruf, Alias disposeAsync und wiederholte Aufrufe

console.log(
  AsyncDisposableStack.prototype[Symbol.asyncDispose] ===
    AsyncDisposableStack.prototype.disposeAsync
);

const stack = new AsyncDisposableStack();
stack.defer(() => console.log("aufgeräumt"));

await stack[Symbol.asyncDispose]();
console.log(stack.disposed);

// Zweiter Aufruf: bewirkt nichts, keine erneute Ausgabe
await stack[Symbol.asyncDispose]();
true aufgeräumt true

Fehlerbehandlung: mehrere Fehler als SuppressedError

const stack = new AsyncDisposableStack();
stack.defer(async () => { throw new Error("A"); });
stack.defer(async () => { throw new Error("B"); });

try {
  await stack[Symbol.asyncDispose]();
} catch (e) {
  // B läuft zuerst (LIFO), danach A; A ist der zuletzt aufgetretene Fehler
  console.log(e instanceof SuppressedError, e.error.message, e.suppressed.message);
}
true A B

Eigene Klasse leitet die Entsorgung an ihren internen Stack weiter

class Sitzung {
  #stack = new AsyncDisposableStack();

  constructor(name) {
    this.name = name;
    this.#stack.defer(async () => console.log(`${name}: Verbindung getrennt`));
    this.#stack.defer(async () => console.log(`${name}: Cache geleert`));
  }

  async [Symbol.asyncDispose]() {
    await this.#stack[Symbol.asyncDispose]();
  }
}

{
  await using sitzung = new Sitzung("S1");
  console.log(`${sitzung.name} aktiv`);
}
S1 aktiv S1: Cache geleert S1: Verbindung getrennt