Start · Sprachen · JavaScript · Referenz · AsyncDisposableStack.prototype.use()

AsyncDisposableStack.prototype.use()

Methode

Registriert einen Wert mit <code>[Symbol.asyncDispose]()</code> (oder <code>[Symbol.dispose]()</code>) auf dem Stapel, damit er beim Entsorgen des Stapels automatisch asynchron aufgeräumt wird.

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

Signatur

AsyncDisposableStack.prototype.use(value)

Beschreibung

use() nimmt eine Ressource entgegen, die das asynchrone Entsorgungsprotokoll umsetzt, also eine Methode [Symbol.asyncDispose]() besitzt. Als Ersatz wird auch eine synchrone [Symbol.dispose]()-Methode akzeptiert. Die Ressource wird auf den Stapel gelegt und beim Aufruf von disposeAsync() oder am Ende eines await using-Blocks automatisch aufgeräumt.

Die Methode gibt den übergebenen Wert unverändert zurück. Deshalb kann man Erzeugung und Registrierung in einer Zeile schreiben: const conn = stack.use(await openConnection()). Das entspricht im Ergebnis einer await using-Deklaration. Der Unterschied: Ressourcen lassen sich so auch dynamisch, bedingt oder in Schleifen registrieren.

Die Entsorgung läuft in umgekehrter Reihenfolge (LIFO): Was zuletzt registriert wurde, wird zuerst aufgeräumt. Jede Entsorgung wird abgewartet, bevor die nächste startet. Werden die Werte null oder undefined übergeben, ignoriert use() sie stillschweigend und gibt sie zurück. So lassen sich optionale Ressourcen ohne zusätzliche Prüfung registrieren.

Ressourcen ohne Entsorgungsprotokoll registriert man mit adopt(). Reine Aufräum-Funktionen hängt man mit defer() an.

Parameter

Name Typ Default Beschreibung
$value Pflicht AsyncDisposable | Disposable | null | undefined Das Objekt, das registriert werden soll. Es muss eine Methode [Symbol.asyncDispose]() oder [Symbol.dispose]() besitzen. null und undefined werden ignoriert.

Rückgabewert

Typ
AsyncDisposable | Disposable | null | undefined
Beschreibung
Genau den übergebenen value, unverändert. So lässt sich der Aufruf direkt in einer Zuweisung verwenden.

Beispiele

Grundlegende Nutzung mit await using

const openFile = async (name) => {
  console.log(`öffne ${name}`);
  return {
    name,
    async [Symbol.asyncDispose]() {
      await new Promise((r) => setTimeout(r, 10));
      console.log(`schließe ${name}`);
    },
  };
};

const main = async () => {
  await using stack = new AsyncDisposableStack();
  const file = stack.use(await openFile('daten.txt'));
  console.log(`arbeite mit ${file.name}`);
}; // hier wird stack.disposeAsync() automatisch abgewartet

await main();
öffne daten.txt arbeite mit daten.txt schließe daten.txt

Mehrere und optionale Ressourcen – Entsorgung in umgekehrter Reihenfolge

const resource = (id) => ({
  id,
  async [Symbol.asyncDispose]() {
    console.log(`entsorge ${id}`);
  },
});

const withCache = false;
const stack = new AsyncDisposableStack();

const db = stack.use(resource('db'));
const cache = stack.use(withCache ? resource('cache') : null); // null wird ignoriert
// Synchron entsorgbare Objekte werden ebenfalls akzeptiert
stack.use({ [Symbol.dispose]() { console.log('entsorge logger (sync)'); } });

console.log(db.id, cache);
await stack.disposeAsync();
console.log('disposed:', stack.disposed);
db null entsorge logger (sync) entsorge db disposed: true

Fabrikfunktion: Ressourcen bei Fehlern aufräumen, bei Erfolg mit move() weitergeben

const connect = async (name) => ({
  name,
  async [Symbol.asyncDispose]() { console.log(`trenne ${name}`); },
});

const createService = async () => {
  await using stack = new AsyncDisposableStack();
  const db = stack.use(await connect('db'));
  const queue = stack.use(await connect('queue'));
  // Schlägt vor dieser Zeile etwas fehl, werden db und queue automatisch getrennt.
  const owned = stack.move(); // Besitz übergeben, stack selbst entsorgt nichts mehr
  return {
    db,
    queue,
    [Symbol.asyncDispose]: () => owned.disposeAsync(),
  };
};

{
  await using service = await createService();
  console.log('Dienst läuft mit', service.db.name, 'und', service.queue.name);
}
Dienst läuft mit db und queue trenne queue trenne db

// Wichtig · Fallstricke

  • TypeError: Ist value weder ein Objekt noch null oder undefined, oder fehlt sowohl [Symbol.asyncDispose] als auch [Symbol.dispose], wirft use() sofort einen TypeError. Für beliebige Werte nimmt man stattdessen adopt().
  • ReferenceError: Wurde der Stapel bereits entsorgt (stack.disposed === true, auch nach move()), führt jeder weitere Aufruf von use() zu einem ReferenceError.
  • Die Entsorgungsmethode wird schon beim Aufruf von use() ausgelesen und gespeichert. Wird sie danach am Objekt ersetzt, hat das keine Wirkung mehr.
  • Werfen mehrere Entsorgungen einen Fehler, laufen trotzdem alle ab. Am Ende wird ein SuppressedError geworfen, der die Fehler verkettet.
  • use() gibt kein Promise zurück und muss nicht mit await aufgerufen werden. Asynchron ist erst disposeAsync().
  • Kompatibilität: Die Methode gehört zum neuen Sprachbestandteil „Explicit Resource Management“. Safari unterstützt sie noch nicht, ältere Umgebungen brauchen ein Polyfill (z. B. aus core-js). Die Syntax await using braucht außerdem Unterstützung durch Transpiler oder Engine.