JavaScript

Guia Completo de Promise.all, Promise.race, Promise.allSettled e Promise.any

9 min de leitura

Guia Completo de Promise.all, Promise.race, Promise.allSettled e Promise.any

Entendendo Promises Combinadas As Promises são a base da programação assíncrona em JavaScript, mas muitas vezes precisamos trabalhar com múltiplas Promises simultaneamente. Para isso, a linguagem oferece métodos estáticos que combinam várias Promises em uma única operação. Estes métodos são essenciais para otimizar fluxos assíncronos, reduzir tempo de execução e tratar cenários complexos de forma elegante. Cada um deles possui um comportamento único, adequado para diferentes situações do desenvolvimento real. Antes de aprofundar nos métodos, lembre-se: uma Promise pode estar em três estados — pendente, resolvida ou rejeitada. Os métodos de combinação tratam esses estados de formas distintas, e é essa diferença que os torna poderosos quando aplicados corretamente. Promise.all: Tudo ou Nada Comportamento e Características O é o método mais comum. Ele retorna uma Promise que se resolve quando todas as Promises do array forem resolvidas, ou rejeita assim que qualquer uma for rejeitada. Pense nele como uma operação "tudo ou nada": ou você consegue todos os dados, ou

<h2>Entendendo Promises Combinadas</h2>

<p>As Promises são a base da programação assíncrona em JavaScript, mas muitas vezes precisamos trabalhar com múltiplas Promises simultaneamente. Para isso, a linguagem oferece métodos estáticos que combinam várias Promises em uma única operação. Estes métodos são essenciais para otimizar fluxos assíncronos, reduzir tempo de execução e tratar cenários complexos de forma elegante. Cada um deles possui um comportamento único, adequado para diferentes situações do desenvolvimento real.</p>

<p>Antes de aprofundar nos métodos, lembre-se: uma Promise pode estar em três estados — pendente, resolvida ou rejeitada. Os métodos de combinação tratam esses estados de formas distintas, e é essa diferença que os torna poderosos quando aplicados corretamente.</p>

<h2>Promise.all: Tudo ou Nada</h2>

<h3>Comportamento e Características</h3>

<p>O <code>Promise.all()</code> é o método mais comum. Ele retorna uma Promise que se resolve quando <strong>todas</strong> as Promises do array forem resolvidas, ou rejeita assim que <strong>qualquer uma</strong> for rejeitada. Pense nele como uma operação &quot;tudo ou nada&quot;: ou você consegue todos os dados, ou falha completamente.</p>

<h3>Exemplo Prático</h3>

<pre><code class="language-javascript">const fetchUser = () =&gt; new Promise(resolve =&gt;

setTimeout(() =&gt; resolve({ id: 1, name: &#039;Ana&#039; }), 1000)

);

const fetchPosts = () =&gt; new Promise(resolve =&gt;

setTimeout(() =&gt; resolve([{ id: 101, title: &#039;Post 1&#039; }]), 1500)

);

const fetchComments = () =&gt; new Promise((resolve, reject) =&gt;

setTimeout(() =&gt; reject(new Error(&#039;Erro ao buscar comentários&#039;)), 800)

);

// Caso com sucesso

Promise.all([fetchUser(), fetchPosts()])

.then(([user, posts]) =&gt; {

console.log(&#039;Usuário:&#039;, user);

console.log(&#039;Posts:&#039;, posts);

})

.catch(err =&gt; console.error(err));

// Caso com falha (rejeita rapidamente no erro)

Promise.all([fetchUser(), fetchPosts(), fetchComments()])

.then(results =&gt; console.log(results))

.catch(err =&gt; console.error(&#039;Erro:&#039;, err.message)); // Saída: Erro: Erro ao buscar comentários</code></pre>

<p>Use <code>Promise.all()</code> quando todos os dados são críticos e a operação deve falhar se qualquer um deles não estiver disponível — como validação de múltiplos campos antes de enviar um formulário.</p>

<h2>Promise.race: O Primeiro a Chegar</h2>

<h3>Comportamento e Características</h3>

<p>O <code>Promise.race()</code> retorna uma Promise que se resolve ou rejeita assim que <strong>a primeira</strong> Promise do array for resolvida ou rejeitada. É uma corrida entre as Promises, e apenas o resultado do &quot;vencedor&quot; importa. Os demais resultados são ignorados, embora continuem executando em background.</p>

<h3>Exemplo Prático</h3>

<pre><code class="language-javascript">const fetchFromServer1 = () =&gt; new Promise(resolve =&gt;

setTimeout(() =&gt; resolve(&#039;Dados do Servidor 1&#039;), 2000)

);

const fetchFromServer2 = () =&gt; new Promise(resolve =&gt;

setTimeout(() =&gt; resolve(&#039;Dados do Servidor 2&#039;), 800)

);

const timeout = () =&gt; new Promise((_, reject) =&gt;

setTimeout(() =&gt; reject(new Error(&#039;Timeout&#039;)), 1000)

);

Promise.race([fetchFromServer1(), fetchFromServer2()])

.then(result =&gt; console.log(result)) // Saída: Dados do Servidor 2 (mais rápido)

.catch(err =&gt; console.error(err));

// Implementar timeout

Promise.race([fetchFromServer1(), timeout()])

.then(result =&gt; console.log(result))

.catch(err =&gt; console.error(&#039;Timeout acionado&#039;)); // Saída: Timeout acionado</code></pre>

<p>Use <code>Promise.race()</code> para implementar timeouts, escolher entre múltiplos servidores (usando o mais rápido) ou quando apenas um resultado é necessário. Cuidado: as Promises descartadas continuam consumindo recursos.</p>

<h2>Promise.allSettled e Promise.any: Os Métodos Modernos</h2>

<h3>Promise.allSettled: Aguarde Todos, Independente do Resultado</h3>

<p>O <code>Promise.allSettled()</code> aguarda <strong>todas</strong> as Promises até que sejam liquidadas (resolvidas ou rejeitadas), retornando um array com objetos descrevendo o resultado de cada uma: <code>{ status: &#039;fulfilled&#039;, value }</code> ou <code>{ status: &#039;rejected&#039;, reason }</code>. Nunca rejeita o resultado final.</p>

<pre><code class="language-javascript">const api1 = Promise.resolve(&#039;Sucesso 1&#039;);

const api2 = Promise.reject(new Error(&#039;Erro 2&#039;));

const api3 = Promise.resolve(&#039;Sucesso 3&#039;);

Promise.allSettled([api1, api2, api3])

.then(results =&gt; {

console.log(results);

/* Saída:

[

{ status: &#039;fulfilled&#039;, value: &#039;Sucesso 1&#039; },

{ status: &#039;rejected&#039;, reason: Error: Erro 2 },

{ status: &#039;fulfilled&#039;, value: &#039;Sucesso 3&#039; }

]

*/

const successes = results.filter(r =&gt; r.status === &#039;fulfilled&#039;)

.map(r =&gt; r.value);

console.log(&#039;Sucessos:&#039;, successes);

});</code></pre>

<p>Use <code>Promise.allSettled()</code> quando você precisa de todos os resultados, mas alguns podem falhar e você quer tratá-los individualmente — como fazer múltiplas requisições a APIs e reportar sucesso/falha de cada uma.</p>

<h3>Promise.any: O Primeiro Sucesso</h3>

<p>O <code>Promise.any()</code> retorna uma Promise resolvida assim que <strong>qualquer uma</strong> das Promises for resolvida com sucesso. Rejeita apenas se <strong>todas</strong> falharem, retornando um <code>AggregateError</code> contendo todas as razões.</p>

<pre><code class="language-javascript">const api1 = Promise.reject(new Error(&#039;API 1 falhou&#039;));

const api2 = Promise.reject(new Error(&#039;API 2 falhou&#039;));

const api3 = new Promise(resolve =&gt;

setTimeout(() =&gt; resolve(&#039;Sucesso na API 3&#039;), 500)

);

Promise.any([api1, api2, api3])

.then(result =&gt; console.log(result)) // Saída: Sucesso na API 3

.catch(err =&gt; console.error(err));

// Todos falham

Promise.any([api1, api2])

.then(result =&gt; console.log(result))

.catch(err =&gt; {

console.error(&#039;Todas falharam:&#039;, err.errors);

// Saída: AggregateError contendo ambos os erros

});</code></pre>

<p>Use <code>Promise.any()</code> para redundância — múltiplos servidores onde qualquer um que responda com sucesso é suficiente. É perfeito para implementar fallbacks automáticos.</p>

<h2>Comparação Prática e Resumo</h2>

<div class="table-wrap"><table><thead><tr><th>Método</th><th>Condição de Sucesso</th><th>Condição de Rejeição</th><th>Resultado</th></tr></thead><tbody><tr><td><code>all()</code></td><td>Todas resolvidas</td><td>Qualquer rejeição</td><td>Array de valores</td></tr><tr><td><code>race()</code></td><td>Primeira a resolver</td><td>Primeira a rejeitar</td><td>Resultado único</td></tr><tr><td><code>allSettled()</code></td><td>Sempre (aguarda todas)</td><td>Nunca</td><td>Array com status de cada uma</td></tr><tr><td><code>any()</code></td><td>Qualquer sucesso</td><td>Todas rejeitadas</td><td>Primeiro valor bem-sucedido</td></tr></tbody></table></div>

<h2>Conclusão</h2>

<p>Dominar esses quatro métodos é fundamental para trabalhar eficientemente com operações assíncronas em JavaScript. <code>Promise.all()</code> garante completude total, <code>Promise.race()</code> otimiza velocidade, <code>Promise.allSettled()</code> oferece granularidade na análise de resultados, e <code>Promise.any()</code> implementa resiliência através de redundância. Na prática, você usará <code>all()</code> em 70% dos casos, mas conhecer os outros diferencia um desenvolvedor senior de um júnior.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all" target="_blank" rel="noopener noreferrer">MDN - Promise.all()</a></li>

<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race" target="_blank" rel="noopener noreferrer">MDN - Promise.race()</a></li>

<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled" target="_blank" rel="noopener noreferrer">MDN - Promise.allSettled()</a></li>

<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any" target="_blank" rel="noopener noreferrer">MDN - Promise.any()</a></li>

<li><a href="https://javascript.info/promise-basics#promise-api" target="_blank" rel="noopener noreferrer">JavaScript.info - Promise combinators</a></li>

</ul>

Comentários

Mais em JavaScript

Boas Práticas de Variáveis de Ambiente e Configuração em Projetos JavaScript para Times Ágeis
Boas Práticas de Variáveis de Ambiente e Configuração em Projetos JavaScript para Times Ágeis

Introdução: Por Que Variáveis de Ambiente Importam Variáveis de ambiente são...

Guia Completo de Currying e Partial Application em JavaScript
Guia Completo de Currying e Partial Application em JavaScript

Entendendo Currying e Partial Application Currying e partial application são...

Guia Completo de Autenticação em Node.js: JWT, Bcrypt e Sessões com Express
Guia Completo de Autenticação em Node.js: JWT, Bcrypt e Sessões com Express

Autenticação em Node.js: JWT, Bcrypt e Sessões com Express Autenticação é o p...