voltar aos artigosasync javascript
$cd~/artigos/promises-javascript-operacoes-assincronas
Async JavaScript
série 33 Conceitos JS·parte 22 de 38

Promises: O Ticket de Pedido do JavaScript Assíncrono

20 minVanderlei José Alamino

E se você pudesse representar um valor que ainda não existe? Em vez de callbacks profundamente aninhados, escrever código assíncrono que lê quase como síncrono?

A resposta é a Promise — objeto que representa a conclusão eventual (ou falha) de uma operação assíncrona. Padronizada no ES6, é um placeholder para um valor que aparecerá depois — como um ticket de pedido que você troca por comida quando estiver pronta.

snippetJavaScript
const promise = new Promise(resolve => {  setTimeout(() => resolve("Olá do futuro!"), 1000);}); promise.then(valor => console.log(valor));

Neste guia da série 33 Conceitos JS — projeto open source criado por Leonardo Maldonado — você vai aprender:

  • Estados pending, fulfilled e rejected
  • .then(), .catch() e .finally()
  • Encadeamento e métodos estáticos
  • Padrões comuns e erros a evitar

Pré-requisito: Callbacks — Promises foram inventadas para resolver problemas de callbacks.

promises-javascript-operacoes-assincronas.meta.jsonjson

// metadados do artigo

{
  "tag": "async javascript",
  "readTime": "20 min",
  "author": "Vanderlei José Alamino",
  "source": "33jsconcepts.com",
  "series": "33 Conceitos JS",
  "part": {
    "current": 22,
    "total": 38
  }
}
abrir fonte original
promises-javascript-operacoes-assincronas.mdmarkdown

Fonte de referência

Conteúdo adaptado a partir do guia original em inglês.

33jsconcepts.com
01

seção

O que é uma Promise?

Uma Promise representa o resultado eventual de uma operação assíncrona. Você não tem o valor agora, mas promete entregar um valor (ou erro) depois.

Diferente de callbacks que você passa para funções, Promises são objetos que você recebe de volta — habilitando encadeamento, composição e tratamento de erro unificado.

snippetJavaScript
const promise = new Promise((resolve, reject) => {  setTimeout(() => resolve("Olá do futuro!"), 1000);}); promise.then(valor => console.log(valor));
02

seção

Analogia: Ticket de Pedido

snippettext
1. Você faz o pedido     → recebe TICKET (Promise)2. Cozinha cozinhando    → PENDING3. Comida pronta         → FULFILLED (resolve)   ou sem ingredientes   → REJECTED (reject)4. Troca ticket por comida → .then()   Problema na cozinha    → .catch()
RestaurantePromise
Ticketconst p = fetch(url)
Esperandopending
Comida chegoufulfilled
Acabou ingredienterejected
Pegar comida.then()
Reclamar.catch()

Uma Promise settled (fulfilled ou rejected) nunca muda de estado — imutabilidade que torna Promises confiáveis em fluxos complexos.

03

seção

Por que Promises?

O inferno de callbacks vs Promises planas:

snippetJavaScript
// ❌ Callbacks aninhadosbuscarUsuario(id, (err, u) => {  if (err) return tratarErro(err);  buscarPedidos(u.id, (err, p) => {    if (err) return tratarErro(err);    buscarDetalhes(p[0].id, (err, d) => { /* ... */ });  });}); // ✅ PromisesbuscarUsuario(id)  .then(u => buscarPedidos(u.id))  .then(p => buscarDetalhes(p[0].id))  .then(d => console.log(d))  .catch(tratarErro);  // um .catch() para toda a cadeia
VantagemExplicação
Estrutura planaSem pirâmide do destino
Erro unificado.catch() na cadeia inteira
ComposiçãoPromise.all, race, etc.
Microtasks.then() sempre assíncrono
RetornoObjetos que você armazena e passa
04

seção

Estados e Destino

snippettext
        PENDING       /       \ FULFILLED   REJECTED       \       /        SETTLED (final)
EstadoDescriçãoMuda?
pendingOperação em andamentoSim
fulfilledSucesso, tem valorNão
rejectedFalha, tem razão (erro)Não
snippetJavaScript
new Promise(resolve => {  resolve("primeiro");  resolve("segundo");  // ignorado  reject("erro");      // ignorado}).then(v => console.log(v));  // "primeiro"

Promise unwrapping: resolver com outra Promise faz a externa "adotar" o estado da interna:

snippetJavaScript
const interna = new Promise(r => setTimeout(() => r("interno"), 1000));Promise.resolve(interna).then(v => console.log(v));  // "interno"

Thenables — qualquer objeto com .then() funciona com Promise.resolve().

05

seção

Criando Promises

snippetJavaScript
const promise = new Promise((resolve, reject) => {  // resolve(valor) ou reject(erro)});

O executor roda sincronamente na criação; apenas .then() é assíncrono:

snippetJavaScript
console.log("1");new Promise(r => { console.log("2"); r("ok"); });console.log("3");Promise.resolve().then(() => console.log("4"));// 1, 2, 3, 4

Encapsulando callbacks:

snippetJavaScript
function delay(ms) {  return new Promise(resolve => setTimeout(resolve, ms));} function loadImage(url) {  return new Promise((resolve, reject) => {    const img = new Image();    img.onload = () => resolve(img);    img.onerror = () => reject(new Error(`Falha: ${url}`));    img.src = url;  });}

Erro no executor → rejeição automática (throw equivale a reject).

06

seção

Consumindo: then, catch, finally

snippetJavaScript
promise  .then(valor => console.log(valor))      // fulfilled  .catch(erro => console.error(erro))       // rejected  .finally(() => esconderSpinner());       // sempre

.catch(onRejected) = .then(undefined, onRejected).

.finally() não recebe argumentos; retorno é ignorado; valor/erro original passa adiante:

snippetJavaScript
Promise.resolve("hello")  .finally(() => "ignorado")  .then(v => console.log(v));  // "hello"

Chave: .then(), .catch() e .finally() retornam novas Promises — isso habilita encadeamento.

07

seção

Encadeamento

snippetJavaScript
Promise.resolve(1)  .then(x => x + 1)   // 2  .then(x => x + 1)   // 3  .then(x => console.log(x));  // 3

Retornar Promise na cadeia — a próxima .then() espera:

snippetJavaScript
buscarUsuario(1)  .then(u => buscarPosts(u.id))  // retorne!  .then(posts => console.log(posts.length));
snippetJavaScript
// ❌ esqueceu return → undefined.then(u => { buscarPosts(u.id); }) // ✅.then(u => buscarPosts(u.id))

Transformação de valores:

snippetJavaScript
Promise.resolve("hello")  .then(s => s.toUpperCase())  .then(s => s + "!")  .then(s => console.log(s));  // HELLO!
08

seção

Tratamento de Erros

Erros pulam .then() até encontrar .catch():

snippetJavaScript
Promise.reject(new Error("Oops!"))  .then(x => x * 2)       // pulado  .then(x => x + 10)      // pulado  .catch(e => console.log(e.message))  // "Oops!"  .then(() => console.log("Recuperado"));

Lançar em .then() rejeita a cadeia. Re-lançar em .catch() propaga para o próximo .catch().

Sempre trate rejeições — rejeição não tratada gera warning (Node pode crashar):

snippetJavaScript
Promise.reject(new Error("Oops!"))  .catch(e => console.error("Tratado:", e.message));
09

seção

Métodos Estáticos

Promise.resolve() / Promise.reject()

snippetJavaScript
Promise.resolve("ok").then(v => console.log(v));Promise.reject(new Error("fail")).catch(e => console.log(e.message));

Promise.all() — todas ou fail-fast

snippetJavaScript
Promise.all([p1, p2, p3]).then(([a, b, c]) => console.log(a, b, c));// Qualquer reject → rejeita imediatamente// [] → resolve com []

Promise.allSettled() — todas, sem curto-circuito

snippetJavaScript
Promise.allSettled([p1, p2]).then(r => {  // [{ status: "fulfilled", value }, { status: "rejected", reason }]});

Promise.race() — primeira a settled

snippetJavaScript
Promise.race([fetch(url), timeout(5000)]);// [] → pending para sempre (bug comum)

Promise.any() — primeira fulfilled

snippetJavaScript
Promise.any([p1, p2]).then(v => console.log(v));// Todas reject → AggregateError// [] → AggregateError imediato
MétodoFulfill quandoReject quando
allTODASQUALQUER
allSettledTODAS settledNunca
racePrimeira settledPrimeira settled
anyQUALQUER fulfillTODAS reject

Promise.withResolvers() (ES2024)

snippetJavaScript
const { promise, resolve, reject } = Promise.withResolvers();setTimeout(() => resolve("Pronto!"), 1000);

Promise.try() (Baseline 2025)

Envolve função sync ou async — captura throws síncronos que Promise.resolve(fn()) não pega:

snippetJavaScript
Promise.try(() => processar()).catch(tratarErro);Promise.try(buscarUsuario, userId);
10

seção

Padrões Comuns

Sequencial — for...of + await ou reduce com Promises.

Paralelo — Promise.all(itens.map(processar)).

Batching — processar em lotes de N com Promise.all por batch.

Retry — loop com try/catch e delay entre tentativas.

Promisify — converter callback error-first em Promise:

snippetJavaScript
function promisify(fn) {  return (...args) => new Promise((resolve, reject) => {    fn(...args, (err, result) => err ? reject(err) : resolve(result));  });}

Node.js: const { promisify } = require("util").

11

seção

Erros Comuns

Esquecer return em .then()

Cadeia quebra — próximo .then() recebe undefined.

Aninhar em vez de encadear

Não recrie inferno de callbacks com .then() dentro de .then().

Anti-padrão do construtor Promise

snippetJavaScript
// ❌ fetch já retorna Promisereturn new Promise((res, rej) => {  fetch(url).then(r => r.json()).then(res).catch(rej);}); // ✅return fetch(url).then(r => r.json());

forEach com async

forEach não espera Promises — use for...of (sequencial) ou Promise.all (paralelo).

Timing de microtasks

snippetJavaScript
console.log("1");Promise.resolve().then(() => console.log("2"));console.log("3");// 1, 3, 2

Veja Event Loop para microtasks vs macrotasks.

12

seção

Perguntas Clássicas de Entrevista

13

seção

Teste Seu Conhecimento

$ summary --quick

Resumo rápido

  • Promise = placeholder para valor futuro ou erro
  • pending → fulfilled/rejected — settled nunca muda
  • .then() retorna nova Promise — habilita encadeamento
  • Sempre retorne de .then() — erro #1 com Promises
  • Erros propagam até .catch() — trate rejeições sempre
  • Promise.all — paralelo fail-fast; allSettled — sucesso parcial
  • race — primeira settled; any — primeira fulfilled
  • Anti-padrão — não envolva fetch em new Promise()
  • Microtasks — .then() roda após código síncrono (A, E, B, C, D)
  • Promises sobre callbacks — .then() ainda é callback por baixo

Créditos da série

Este artigo faz parte de uma série de estudos inspirada no projeto 33 Conceitos JS, criado por Leonardo Maldonado. Todo o conteúdo original está disponível em 33jsconcepts.com.