Ce face util.promisify
Multe funcții vechi din Node.js și din pachete primesc ca ultim argument un callback de forma (eroare, rezultat) => {}. promisify(f) întoarce o funcție nouă, care primește aceleași argumente fără callback și întoarce o promisiune: rezolvată cu rezultatul sau respinsă cu eroarea. Așa le poți folosi cu await.
Pentru majoritatea modulelor de bază există deja variante cu promisiuni (node:fs/promises, node:timers/promises, node:stream/promises). promisify rămâne util pentru exec, scrypt, zlib.gzip și pentru pachete mai vechi.
Unele funcții au o variantă pregătită, marcată cu util.promisify.custom; promisify o folosește automat (de aceea promisify(exec) întoarce { stdout, stderr }). callbackify face invers: dintr-o funcție async face una cu callback.
Parametri
| Parametru | Descriere |
|---|---|
f |
O funcție al cărei ultim argument este un callback (eroare, valoare). |
Ce returnează
O funcție care întoarce o promisiune.
Exemple
Exemplul 1: O funcție veche cu callback
import { promisify } from "node:util";
function cautaElev(nume, callback) {
const note = { Ana: [10, 9], Ion: [7, 8] };
setTimeout(() => {
if (!(nume in note)) return callback(new Error(`Elevul ${nume} nu există`));
callback(null, note[nume]);
}, 5);
}
const cautaElevAsync = promisify(cautaElev);
console.log(await cautaElevAsync("Ana"));
try {
await cautaElevAsync("Maria");
} catch (eroare) {
console.log(eroare.message);
}
Rezultat
[ 10, 9 ]
Elevul Maria nu există
Exemplul 2: Funcții din Node.js: exec și zlib
import { promisify } from "node:util";
import { exec } from "node:child_process";
import { gzip, gunzip } from "node:zlib";
const { stdout } = await promisify(exec)("echo Bună ziua");
console.log(stdout.trim());
const comprimat = await promisify(gzip)("text de comprimat");
console.log((await promisify(gunzip)(comprimat)).toString());
Rezultat
Bună ziua
text de comprimat
Exemplul 3: callbackify: invers
import { callbackify } from "node:util";
async function totalComanda(produse) {
return produse.reduce((s, p) => s + p, 0);
}
const totalCuCallback = callbackify(totalComanda);
totalCuCallback([12, 30, 7.5], (eroare, total) => {
console.log(eroare, total);
});
Rezultat
null 49.5
Greșeli frecvente
- Aplici
promisifype o funcție al cărei callback nu are eroarea pe primul loc (de exemplusetTimeout(fn, ms)sau un callback(rezultat) =>): promisiunea nu se rezolvă corect. - Aplici
promisifype o metodă și pierzithis:promisify(obiect.metoda)apelează metoda fără obiect. Scriepromisify(obiect.metoda.bind(obiect)). - Folosești
promisify(fs.readFile)în cod nou: există dejaimport { readFile } from "node:fs/promises".
Comenzi înrudite
child_process.exec: Rulează o comandă în shell (ca în terminal) și primește la final tot textul afișat de ea.crypto.scrypt (parole): Transformă o parolă într-o cheie greu de spart, cu sare aleatorie: modul corect de a salva parolele cu modulele Node.js.zlib (gzip, brotli): Comprimă și decomprimă date cu gzip, deflate sau Brotli: fișiere .gz, răspunsuri HTTP mai mici.fs.readFile: Citește tot conținutul unui fișier: ca text dacă dai codificarea („utf8”), altfel ca Buffer cu octeții bruți.timers/promises (setTimeout cu await): Variantele cu promisiuni ale temporizatoarelor: await setTimeout(1000) pentru o pauză, setInterval ca iterator asincron.