Signatur
Beschreibung
Die Eigenschaft disposed hat nur einen Getter und kann nicht beschrieben werden. Sie zeigt, ob ein AsyncDisposableStack noch aktiv ist. Den Wert true gibt sie in zwei Fällen zurück:
- Auf dem Stack wurde
disposeAsync()aufgerufen. Das kann direkt im Code passieren oder automatisch am Ende eines Blocks mitawait using. - Die Ressourcen wurden mit
move()an einen neuen Stack übergeben. Der alte Stack gilt danach ebenfalls als entsorgt.
Die Eigenschaft ist vor allem als Schutzprüfung nützlich. Auf einem entsorgten Stack werfen use(), adopt(), defer() und move() einen ReferenceError. Mit disposed lässt sich das vorher prüfen, zum Beispiel in eigenen Klassen, die einen Stack intern nutzen und selbst ein disposed-Flag anbieten.
Wichtig: Der Zustand wechselt synchron, sobald disposeAsync() aufgerufen wird. Die asynchronen Aufräumfunktionen können dann noch laufen. disposed === true heißt also nicht, dass das Aufräumen schon fertig ist. Dafür muss man auf das Promise von disposeAsync() warten.
Rückgabewert
true, wenn der Stack entsorgt oder verschoben wurde, sonst false.Beispiele
Zustand vor und nach disposeAsync()
const stack = new AsyncDisposableStack();
stack.defer(async () => {
console.log('Verbindung geschlossen');
});
console.log(stack.disposed);
const p = stack.disposeAsync();
// Schon vor dem await true, auch wenn das Aufräumen noch läuft
console.log(stack.disposed);
await p;
console.log(stack.disposed);
Nach move() gilt der alte Stack als entsorgt
const openResources = async () => {
await using stack = new AsyncDisposableStack();
stack.defer(async () => console.log('Datei geschlossen'));
// Ressourcen an den Aufrufer übergeben, bevor der Block endet
const moved = stack.move();
console.log('alt:', stack.disposed, '| neu:', moved.disposed);
return moved;
};
const resources = await openResources();
// Am Blockende wird nichts aufgeräumt, weil der alte Stack leer ist
await resources.disposeAsync();
Schutzprüfung in einer eigenen Klasse
class DbSession {
#stack = new AsyncDisposableStack();
get disposed() {
return this.#stack.disposed;
}
track(cleanup) {
if (this.#stack.disposed) {
throw new Error('Sitzung bereits beendet');
}
this.#stack.defer(cleanup);
}
async [Symbol.asyncDispose]() {
await this.#stack.disposeAsync();
}
}
const session = new DbSession();
session.track(async () => console.log('Transaktion zurückgerollt'));
await session[Symbol.asyncDispose]();
console.log(session.disposed);
try {
session.track(async () => {});
} catch (err) {
console.log(err.message);
}
// Wichtig · Fallstricke
- Kein Signal für fertiges Aufräumen:
disposedist direkt nach dem Aufruf vondisposeAsync()schontrue, auch wenn die asynchronen Aufräumfunktionen noch laufen. Wenn der Code auf das Ende des Aufräumens angewiesen ist, muss er auf das zurückgegebene Promise warten. - Auf einem entsorgten Stack werfen
use(),adopt(),defer()undmove()einenReferenceError. Ein zweiter Aufruf vondisposeAsync()dagegen macht nichts und gibt ein erfülltes Promise zurück. - Die Eigenschaft kann nur gelesen werden. Eine Zuweisung wird ignoriert, im Strict Mode wirft sie einen
TypeError. Wird der Getter auf einem Objekt aufgerufen, das keinAsyncDisposableStackist, gibt es ebenfalls einenTypeError. - Kompatibilität: Die Eigenschaft gehört zum Vorschlag „Explicit Resource Management“ (
using/await using). Chromium-Browser ab Version 134, Firefox ab 141 und Node.js ab 24 unterstützen sie. Safari hat sie noch nicht. Für ältere Umgebungen gibt es Polyfills, etwacore-js, oder man lässt Babel/TypeScript den Code umwandeln.