Assíncrono · unidade 21 de 27

Combinadores de Promise

O combinador certo começa no contrato de falha.

9 min de leitura · 7 cards · 16 exercícios

Card 1 de 7: Combinadores de Promise01 / 07

Leitura

Promise.all, allSettled, race e any como decisões explícitas sobre resultados completos, parciais e concorrentes.

No backend, esse fundamento aparece quando o código transforma entrada em decisão. O detalhe de linguagem deixa de ser acadêmico no momento em que altera um payload, uma regra de negócio ou a forma como uma falha chega à camada seguinte.

A forma mais útil de estudar é ligar a sintaxe a um contrato observável: o que entra, o que pode mudar, qual resultado sai e qual erro deve continuar o fluxo. É esse raciocínio que os exemplos e exercícios desta unidade procuram treinar.

Código

exemplo.js
const results = await Promise.allSettled(tasks)

const failures = results.filter(
  result => result.status === "rejected"
)

O que fica

  • Promise.all é fail-fast quando todos os resultados são obrigatórios.
  • AllSettled preserva sucessos e falhas por item.
  • Race escolhe o primeiro settled; any, o primeiro fulfilled.

Prática guiada.Leia, rode, quebre e explique cada exercício.

Prática guiada / unidade 21

Um problema de cada vez.

Leia o contrato, escreva sua tentativa e confira os casos esperados. A resolução de referência permanece visível ao final de cada exercício.

Fundamentalexercício 01 / 16

fetchAllUsersAll(ids, fetchUserAsyncFn)

01 / Entenda

Enunciado

usa Promise.all para buscar todos os usuários de ids em paralelo. Se qualquer busca falhar, a função inteira rejeita.

02 / Implemente

Sua tentativa

Comece pela assinatura e resolva sem olhar a resposta.

ponto de partida
async function fetchAllUsersAll(ids, fetchUserAsyncFn) {
  // Escreva sua solução aqui.
}

03 / Preveja

Entrada e saída

Use estes exemplos para entender o contrato antes de programar.

Entrada / chamada

fetchAllUsersAll([1, 2, 3], fetchUserAsyncFn)

Erro esperado

lança /não encontrado/

04 / Teste

Prove que funciona

O teste chama sua função e compara o resultado real com o esperado.

Como utilizar este teste

  1. 01Implemente a função usando exatamente o nome e os parâmetros do enunciado.
  2. 02Salve sua implementação em exercises.js, na mesma pasta do teste.
  3. 03Abra o terminal nessa pasta e execute o comando abaixo.
  4. 04Se falhar, compare “esperado” com “recebido”; essa diferença mostra o caso que precisa ser corrigido.
node --test --test-name-pattern="fetchAllUsersAll" exercises.test.js

Comportamentos cobertos

  • resolve com todos os usuários quando tudo dá certo
  • rejeita se qualquer busca falhar
Ver código completo do teste
test("fetchAllUsersAll: resolve com todos os usuários quando tudo dá certo", async () => {
  const fetchUserAsyncFn = async (id) => ({ id, name: `Usuário ${id}` });
  const result = await fetchAllUsersAll([1, 2, 3], fetchUserAsyncFn);
  assert.deepEqual(result, [
    { id: 1, name: "Usuário 1" },
    { id: 2, name: "Usuário 2" },
    { id: 3, name: "Usuário 3" },
  ]);
});

test("fetchAllUsersAll: rejeita se qualquer busca falhar", async () => {
  const fetchUserAsyncFn = async (id) => {
    if (id === 2) throw new Error("usuário 2 não encontrado");
    return { id };
  };
  await assert.rejects(
    () => fetchAllUsersAll([1, 2, 3], fetchUserAsyncFn),
    /não encontrado/,
  );
});

Ainda travou?

Dicas graduais

Nível 1 — direção, sem código

Para fetchAllUsersAll vs fetchAllUsersSettled: os dois recebem os mesmos parâmetros. O que muda no comportamento observável quando uma das buscas falha?

Nível 2 — pista mais direta

fetchAllUsersAll: return Promise.all(ids.map((id) => fetchUserAsyncFn(id)));

05 / Compare

Resolução

Esta área permanece livre em todos os exercícios. O código atual da unidade aparece abaixo para comparação com os testes e casos esperados.
código disponível
async function fetchAllUsersAll(ids, fetchUserAsyncFn) {
  throw new Error("not implemented: fetchAllUsersAll");
}