MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Funcțiile Promise.all, Promise.allSettled, Promise.any și Promise.race

Funcțiile Promise.all(), Promise.allSettled() și Promise.race() permit gruparea executării mai multor promise-uri.

Funcția Promise.all

Funcția Promise.all() returnează un singur obiect Promise care încorporează un set de promise-uri.

Considerăm codul următor:

const promise1 = new Promise((resolve, reject) => {
   setTimeout(resolve, 1000, "Hello");
});
const promise2 = new Promise((resolve, reject) => {
   setTimeout(resolve, 500, "World");
});
promise1.then(value => console.log(value));  // Hello
promise2.then(value => console.log(value));  // World

Aici sunt definite două promise-uri. Operațiunea asincronă a primului promise este executată după 1000 de milisecunde, iar a două după 500 de milisecunde. Ambele promise-uri sunt executate independent una de cealaltă. Ieșirea în consolă:

World
Hello

Funcția Promise.all() permite combinarea mai multor promise-uri și executarea lor în paralel, ca un întreg. Ca parametru, funcția acceptă un set de promise-uri:

Promise.all([promise1, promise2, ... promiseN]);

Rezultatul returnat de funcție este un nou obiect Promise.

Acum să modificăm exemplul anterior, utilizând funcția Promise.all():

const promise1 = new Promise((resolve, reject) => {
   setTimeout(resolve, 1000, "Hello");
});
const promise2 = new Promise((resolve, reject) => {
   setTimeout(resolve, 500, "World");
});
Promise.all([promise1, promise2])
   .then(values => {
       const [promise1data, promise2data] = values;
       console.log(promise1data, promise2data);    // Hello World
});

Acum datele ambelor promise-uri sunt returnate împreună și sunt accesibile în metoda then() sub forma unui array values. Ieșirea în consolă:

Hello World

Valorile tuturor promise-urilor sunt returnate doar dacă toate s-au încheiat cu succes. Dar dacă în operațiunea asincronă a oricărui promise apare o eroare din cauza logicii interne sau a apelării funcției reject(), atunci toate promise-urile trec în starea rejected, respectiv:

const promise1 = new Promise((resolve, reject) => {
   reject("Eroare neașteptată");
   setTimeout(resolve, 500, "Hello");
});
const promise2 = new Promise((resolve, reject) => {
   setTimeout(resolve, 1000, "World");
});

Promise.all([promise1, promise2])
   .then(values => {
       const [promise1data, promise2data] = values;
       console.log(promise1data, promise2data);
})
.catch(error => console.log(error)); // Eroare neașteptată

În acest caz, primul promise este explicit trecut în starea rejected, deci toate promise-urile transmise în funcția Promise.all() sunt trecute în aceeași stare. Și ulterior, prin metoda catch(), ca și în cazul general, putem trata eroarea apărută.

Promise.allSettled

O altă funcție - Promise.allSettled() - la fel ca Promise.all() acceptă un set de promise-uri și le execută ca un întreg, dar returnează un obiect cu statutul și rezultatul fiecărui promise:

const promise1 = new Promise((resolve, reject) => {
   reject("Eroare neașteptată");
   setTimeout(resolve, 500, "Hello");
});
const promise2 = new Promise((resolve, reject) => {
   setTimeout(resolve, 1000, "World");
});
 
Promise.allSettled([promise1, promise2])
   .then(values => {
       const [promise1data, promise2data] = values;
       console.log(promise1data);  // {status: "rejected", reason: "Eroare neașteptată"}
       console.log(promise2data);  // {status: "fulfilled", value: "World"}
});

În acest caz, chiar și în prezența unei erori în unul din promise-uri (ca în cazul primului promise de mai sus), funcția transmite rezultatele metodei then(), care urmează în lanț. Fiecare rezultat reprezintă un obiect. Prima proprietate a acestui obiect - status - descrie statutul sau starea promise-ului.

Dacă a apărut o eroare, statutul este rejected, iar a doua proprietate reprezintă obiectul erorii. Dacă promise-ul a fost executat cu succes, atunci statusul este fulfilled, iar a doua proprietate - value - conține rezultatul promise-ului.

Promise.race

Funcția Promise.race() acceptă, de asemenea, mai multe promise-uri, dar returnează primul promise care se finalizează (indiferent dacă se finalizează cu succes sau cu o eroare):

const promise1 = new Promise((resolve) => {
   setTimeout(resolve, 500, "Hello");
});
const promise2 = new Promise((resolve) => {
   setTimeout(resolve, 1000, "World");
});
Promise.race([promise1, promise2])
   .then(value => console.log(value))       // Hello
   .catch(error => console.log(error));

În acest caz, primul promise finalizat va fi promise1. Astfel, în metoda then(value => console.log(value)), value va fi șirul "Hello".

Promise.any

Funcția Promise.any() acceptă mai multe promise-uri și returnează primul promise care se finalizează cu succes:

const promise1 = new Promise((resolve, reject) => {
   reject("error in promise1");
   setTimeout(resolve, 500, "Hello");
});
const promise2 = new Promise((resolve) => {
   setTimeout(resolve, 1000, "World");
});
Promise.any([promise1, promise2])
   .then(value => console.log(value))       // World
   .catch(error => console.log(error));

În acest caz, primul promise finalizat va fi promise1, dar se finalizează cu o eroare. Prin urmare, în metoda then(value => console.log(value)), value va fi șirul "World" - rezultatul promise-ului promise2, care se finalizează cu succes.

Se poate părea că Promise.any face același lucru ca și Promise.race, dar aceste funcții diferă în ceea ce privește modul în care gestionează promise-urile care se finalizează cu o eroare. Promise.race returnează primul promise finalizat, indiferent dacă se finalizează cu o eroare sau nu.

În schimb, Promise.any returnează primul promise finalizat cu succes (dacă există). Dacă toate promise-urile se finalizează cu o eroare, atunci se generează o excepție de tipul AggregateError:

const promise1 = new Promise((resolve, reject) => {
   reject("error in promise1");
   setTimeout(resolve, 500, "Hello");
});
const promise2 = new Promise((resolve, reject) => {
   reject("error in promise2");
   setTimeout(resolve, 1000, "World");
});
Promise.any([promise1, promise2])
   .then(value => console.log(value))
   .catch(error => console.log(error)); // AggregateError: All promises were rejected

Prin intermediul proprietății errors a tipului AggregateError se pot obține sub forma unui array toate erorile care au apărut în promise-uri:

const promise1 = new Promise((resolve, reject) => {
   reject("error in promise1");
   setTimeout(resolve, 500, "Hello");
});
const promise2 = new Promise((resolve, reject) => {
   reject("error in promise2");
   setTimeout(resolve, 1000, "World");
});
Promise.any([promise1, promise2])
   .then(value => console.log(value))
   .catch(e => console.log(e.errors));  // ["error in promise1", "error in promise2"]
← Lecția anterioară Lecția următoare →