Funções Promise.all, Promise.allSettled, Promise.any e Promise.race - JavaScript

As funções Promise.all, Promise.allSettled, Promise.any e Promise.race permitem agrupar a execução de várias promises.

Função Promise.all

A função Promise.all recebe um array de promises e retorna uma nova promise que é resolvida quando todas as promises do array forem resolvidas ou rejeitada quando uma das promises for rejeitada.

Vamos analisar o seguinte código:

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

Aqui, definimos duas promises. A operação assíncrona da primeira promise é executada após 1000 milissegundos, enquanto a ação da segunda promise é executada após 500 milissegundos. Ambas as promises são executadas independentemente uma da outra. A saída no console é:

Hello
World

A função Promise.all() permite combinar várias promises e executá-las em paralelo como uma única unidade. Como parâmetro, a função aceita um conjunto de promises:

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

O resultado retornado pela função é um novo objeto Promise.

Agora, vamos alterar o exemplo anterior usando a função 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
    });

Agora, os dados de ambas as promises são retornados juntos e estão disponíveis no método then() como um array de values. A saída no console será:

Hello World

Os valores de todas as promises são retornados somente se todas forem concluídas com sucesso. No entanto, se uma operação assíncrona de pelo menos uma promise falhar devido à lógica interna ou ao chamar a função reject(), todas as promises entrarão no estado de rejeição (rejected), como mostrado a seguir:

const promise1 = new Promise((resolve, reject) => {
    reject("Erro inesperado");
    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)); // Erro inesperado

Neste caso, explicitamente colocamos a primeira promise no estado de rejeição (rejected), e, consequentemente, todas as promises passadas para a função Promise.all() também entram neste estado. Em seguida, através do método catch(), podemos tratar o erro ocorrido.

Promise.allSettled

Outra função é a Promise.allSettled(), que assim como Promise.all(), aceita um conjunto de promises e as executa como uma unidade, mas retorna um objeto com o status e o resultado da promise:

const promise1 = new Promise((resolve, reject) => {
    reject("Erro inesperado");
    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: "Erro inesperado"}
        console.log(promise2data);  // {status: "fulfilled", value: "World"}
    });

Quando ocorre um erro em uma das promises (como no exemplo acima com a primeira promise), a função ainda passa os resultados para o método then(), que segue na cadeia. Cada resultado representa um objeto. A primeira propriedade deste objeto, status, descreve o status ou estado da promise. Se ocorreu um erro, o status será rejected, e a segunda propriedade representará o objeto de erro. Se a promise foi concluída com sucesso, o status será fulfilled, e a segunda propriedade, value, armazenará o resultado da promise.

Promise.race

A função Promise.race() também aceita várias promises, mas retorna a primeira promise que for concluída (independentemente de ter sido concluída com sucesso ou erro):

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));

Neste caso, a primeira promise concluída será a promise1. Portanto, no método then(value => console.log(value)), o valor será a string "Hello".

Promise.any

A função Promise.any() aceita várias promises e retorna a primeira promise que foi concluída com sucesso:

const promise1 = new Promise((resolve, reject) => {
    reject("erro na 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));

Neste caso, a primeira promise concluída será a promise1, porém, ela termina com um erro. Portanto, no método then(value => console.log(value)), o valor será a string "World", que é o resultado da promise2, que foi concluída com sucesso.

Pode parecer que Promise.any() faz o mesmo que Promise.race(), mas essas funções diferem na forma como lidam com promises que foram concluídas com erro. Promise.race() retorna a primeira promise concluída, independentemente de ter sido concluída com erro ou não. Já Promise.any() retorna a primeira promise que foi concluída com sucesso (se houver). Se todas as promises foram concluídas com erro, uma exceção do tipo AggregateError é gerada:

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

Com a propriedade errors do tipo AggregateError, é possível obter todas as falhas ocorridas nas promises em forma de array:

const promise1 = new Promise((resolve, reject) => {
    reject("erro na promise1");
    setTimeout(resolve, 500, "Hello");
});
const promise2 = new Promise((resolve, reject) => {
    reject("erro na promise2");
    setTimeout(resolve, 1000, "World");
});
Promise.any([promise1, promise2])
    .then(value => console.log(value)) 
    .catch(e => console.log(e.errors));  // ["erro na promise1", "erro na promise2"]
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com