Ce face using (resurse)
using declară o variabilă ca const, dar cu o promisiune în plus: când execuția iese din blocul curent (normal, cu return sau printr-o eroare), se apelează automat metoda [Symbol.dispose]() a obiectului. Este echivalentul lui try/finally pentru fișiere deschise, conexiuni, blocări sau cronometre, fără să mai scrii finally de mână.
Obiectul trebuie să implementeze interfața Disposable (metoda [Symbol.dispose]). await using lucrează cu AsyncDisposable ([Symbol.asyncDispose], care returnează un Promise) și așteaptă eliberarea. Dacă declari mai multe resurse, sunt eliberate în ordine inversă. DisposableStack adună mai multe resurse sau funcții de curățare într-un singur obiect.
Este o funcție nouă din JavaScript (propunerea „Explicit Resource Management”), suportată de Node.js 24+ și browserele recente; TypeScript o poate transforma pentru medii mai vechi. Tipurile sunt în biblioteca esnext.disposable (incluse și de @types/node).
Exemple
Exemplul 1: Eliberare automată, în ordine inversă
class Resursa implements Disposable {
constructor(readonly nume: string) {
console.log("deschid", nume);
}
[Symbol.dispose](): void {
console.log("închid", this.nume);
}
}
function lucreaza(): string {
using fisier = new Resursa("note.csv");
using conexiune = new Resursa("baza de date");
console.log(`lucrez cu ${fisier.nume} și ${conexiune.nume}`);
return "gata";
}
console.log(lucreaza());
Rezultat
deschid note.csv
deschid baza de date
lucrez cu note.csv și baza de date
închid baza de date
închid note.csv
gata
Exemplul 2: Eliberare și când apare o eroare
Resursa este închisă înainte ca eroarea să ajungă la catch.
function blocare(nume: string): Disposable {
console.log(`blochez ${nume}`);
return { [Symbol.dispose]: () => console.log(`deblochez ${nume}`) };
}
try {
using _b = blocare("catalog");
throw new Error("nota nu este validă");
} catch (e) {
console.log("eroare:", (e as Error).message);
}
Rezultat
blochez catalog
deblochez catalog
eroare: nota nu este validă
Exemplul 3: await using cu un fișier temporar
import { open, rm } from "node:fs/promises";
async function fisierTemporar(nume: string) {
const f = await open(nume, "w");
return {
f,
async [Symbol.asyncDispose]() {
await f.close();
await rm(nume);
console.log(`${nume} a fost șters`);
},
};
}
{
await using tmp = await fisierTemporar("raport.tmp");
await tmp.f.writeFile("Ana,10\nMihai,9\n");
console.log("scris:", (await tmp.f.stat()).size, "octeți");
}
console.log("după bloc");
Rezultat
scris: 15 octeți
raport.tmp a fost șters
după bloc
Greșeli frecvente
- Folosești
usingpe un obiect fără[Symbol.dispose]. tsc dă The initializer of a ‘using’ declaration must be either an object with a ‘[Symbol.dispose]()’ method, or be ‘null’ or ‘undefined’. - Folosești
usingpentru o resursă asincronă. Eliberarea nu este așteptată; scrieawait using.
Comenzi înrudite
bigint și symbol: bigint ține numere întregi oricât de mari; symbol este o valoare unică, folosită de obicei drept cheie de proprietate.async/await cu tipuri: O funcție async returnează mereu Promise<T>; await scoate valoarea de tip T din Promise.implements: O clasă promite că respectă una sau mai multe interfețe; tsc verifică dacă are toți membrii ceruți.interface: Descrie forma unui obiect: ce proprietăți are, de ce tip sunt și ce metode are.