[pt-BR] ES2020: Promise.allSettled
Mesaque Francisco
Posted on January 27, 2020
Uma nova adição que chega com o ES2020 é Promise.allSettled
. Esse novo método chega para resolver um problema que deixava o código muito verboso na utilização de Promise.all
.
Relembrando: Promises
Promise
é um objeto usado para processamento assíncrono. Uma Promise
representa um valor que pode estar disponível agora, no futuro ou nunca.
UmaPromise
pode se encontrar em algum dos estados:
- pending (pendente): Estado inicial, que não foi realizada nem rejeitada.
- fulfilled (realizada): Sucesso na operação.
- rejected (rejeitada): Falha na operação.
- settled (estabelecida): Que foi realizada ou rejeitada.
Uma promessa pendente pode ter seu estado alterado para realizada com um valor ou ser rejeitada com um motivo (erro).
Relembrando: Promise.all
Promise.all
é um método que recebe um objeto iterável contendo promises. Promise.all
apenas retorna uma promise fulfilled
caso todas as promises que foram passadas no objeto sejam também fulfilled
caso contrário irá retornar uma promise com estado rejected
.
Promise.allSettled
Promise.allSettled
funciona de forma similar a Promise.all
com a diferença que a promise resultante nunca é rejeitada caso uma das promises do objeto iterado seja rejeitada. Ao invés disso retorna um array com um objeto para cada promise contendo as propriedades:
- status:
fulfilled
|rejected
- value: valor da promise resolvida
- reason: motivo da promise rejeitada
O novo método Promise.allSettled
é bem útil quando você precisa executar uma operação que deve ser considerada completa independente de suas etapas falharem ou não. Como por exemplo, quando você quer fazer download de multiplos arquivos e ao final executar alguma outra ação.
Usando Promise.all
você teria que adicionar um .catch
para cada promise que será executada. Para evitar que o retorno de Promise.all
seja uma promise rejeitada.
const download = async (url) => {/*...*/};
const handleFailedDownload = async url => {/*...*/};
const downloadAllFiles = async () => {
const urls = [
"http://example.com/exists.txt",
"http://example.com/missing-file.txt"
];
await Promise.all(urls.map(url => download(url).catch(handleFailedDownload)));
doSomethingElse();
};
Usando Promise.allSettled
você não precisa mais se preocupar com promises sendo rejeitadas em um loop. Porém ter
const download = async (url) => {/*...*/};
const downloadAllFiles = async () => {
const urls = [
'http://example.com/exists.txt',
'http://example.com/missing-file.txt'
];
await Promise.allSettled(urls.map(url => download(url));
doSomethingElse();
};
Atenção com os valores retornados
Diferente de Promise.all
onde em caso de sucesso, os valores são retornados diretamente no array de resultados. Em Promise.allSettled
o array de resultados retorna contém um SettlementObject
para cada promise passada no iterável inicial.
Abaixo você encontra uma representação da assinatura dos retornos de Promise.allSettled
.
type SettlementObject<T> = FulFillmentObject<T> | RejectionObject<T>;
interface SettlementObject<T> {
status: "fulfilled";
value: T;
}
interface RejectionObject {
status: "rejected";
reason: unknown;
}
Exemplo de Promise.allSettled
const results = Promise.allSettled([
Promise.resolve("OK"),
Promise.reject("ERROR"),
Promise.resolve("OK TOO")
]);
console.log(results);
/**
Expected output:
[
{ status: 'fulfilled', value: 'OK' },
{ status: 'rejected', reason: 'ERROR' },
{ status: 'fulfilled', value: 'OK TOO'},
]
*/
Posted on January 27, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.