W3docs

Promises em JavaScript

Aprenda Promises em JavaScript: estados pending, fulfilled e rejected, a função executora com resolve e reject, then/catch/finally e microtarefas, com exemplos executáveis.

As Promises em JavaScript são uma ferramenta poderosa para gerenciar operações assíncronas, permitindo que os desenvolvedores escrevam código mais limpo e robusto. Este capítulo explica o que é uma promise, os três estados em que ela pode estar, como a função executora funciona com resolve e reject, como consumir resultados com .then, .catch e .finally, e quando os callbacks de promise realmente são executados (a fila de microtarefas). Compreender esses fundamentos é essencial antes de avançar para encadeamento, a Promise API e async/await.

Introdução às Promises em JavaScript

Uma Promise é um objeto que representa um valor que pode não estar disponível ainda, mas estará em algum momento no futuro. Em vez de passar um callback para uma função assíncrona e torcer para que ele seja chamado, você recebe um objeto promise imediatamente e anexa callbacks a ele. Isso evita callbacks profundamente aninhados, frequentemente chamados de "callback hell", e oferece uma maneira única e consistente de lidar com sucesso e falha.

Uma tarefa assíncrona típica — uma requisição de rede, um timer, a leitura de um arquivo — não tem seu resultado pronto imediatamente. A promise é um placeholder para esse resultado.

Os Três Estados de uma Promise

Uma promise está sempre em exatamente um dos três estados:

  • pending — o estado inicial; a operação ainda não foi concluída.
  • fulfilled — a operação foi concluída com sucesso e a promise tem um valor.
  • rejected — a operação falhou e a promise tem um motivo (geralmente um Error).

Uma promise pendente pode fazer a transição para fulfilled ou rejected. Uma vez que isso ocorra, ela está settled e nunca mais pode mudar de estado. Essa transição única e unidirecional é o que torna as promises previsíveis: um callback .then anexado a uma promise já cumprida ainda será executado, e uma promise nunca pode voltar do estado fulfilled para rejected.

                  ┌─────────────┐  resolve(value)   ┌─────────────┐
                  │   pending   │ ────────────────▶ │  fulfilled  │
   new Promise ─▶ │             │                   └─────────────┘
                  │             │  reject(reason)   ┌─────────────┐
                  └─────────────┘ ────────────────▶ │  rejected   │
                                                    └─────────────┘

Criando uma Promise

Para criar uma promise, você chama o construtor Promise e passa uma função chamada de executor. O executor é executado imediata e sincronicamente no momento em que a promise é criada. Ele recebe duas funções como argumentos, convencionalmente chamadas de resolve e reject:

  • Chame resolve(value) para cumprir a promise com value.
  • Chame reject(reason) para rejeitar a promise com reason.

Até que você chame uma delas, a promise permanece pending.


javascript— editable

O executor recebe resolve e reject para que possa liquidar a promise assim que o trabalho assíncrono terminar. Aqui a promise é cumprida após um timer de um segundo:


javascript— editable

Nota: Apenas a primeira chamada a resolve ou reject importa. Uma vez que a promise está settled, quaisquer chamadas adicionais a resolve ou reject são ignoradas. Além disso, se o executor lançar um erro de forma síncrona, a promise é automaticamente rejeitada com esse erro.

Tratando Resultados com .then, .catch e .finally

Uma vez que uma promise foi criada, você consome seu resultado com os métodos .then, .catch e .finally. É assim que o restante do seu código reage a uma promise settled.

O método then

O método .then é usado para agendar um callback a ser executado quando a promise é cumprida. Para que uma promise seja cumprida, o método resolve deve ser chamado. O argumento que você passa para o método resolve será o valor final da promise.


javascript— editable

Neste código, a promise só será cumprida após o timeout de 1000 ms, e o método resolve é chamado com "Done!".

A função na parte then só é executada após o método resolve ser chamado.

.then também pode receber um segundo argumento — um handler de rejeição — mas usar um .catch separado (abaixo) é mais claro e captura erros de handlers anteriores também.

O método .catch

O método .catch é usado para tratar a promise caso ela seja rejeitada. Isso significa que um erro foi lançado no bloco da função da promise ou que o método reject foi chamado.


javascript— editable

Para padrões de tratamento de erros mais avançados — rejeição versus erros lançados, relançamento e recuperação dentro de uma cadeia — consulte Tratamento de Erros com Promises.

O método .finally

O método .finally permite executar código após a promise estar settled, independentemente do resultado. Ele não recebe argumentos (não sabe se a promise foi cumprida ou rejeitada) e passa o resultado ou erro sem alterações, sendo ideal para limpeza, como ocultar um indicador de carregamento.


javascript— editable

Quando os Callbacks de Promise São Executados? (Microtarefas)

Uma surpresa comum é que os callbacks de .then, .catch e .finally nunca são executados de forma síncrona, mesmo que a promise já esteja settled. Eles são agendados na fila de microtarefas, que o motor processa somente após o código síncrono atual terminar.

Isso significa que o código síncrono sempre é executado primeiro, e os callbacks de promise são executados antes dos timers (setTimeout), que ficam na fila de macrotarefas separada.


javascript— editable

Mesmo que a promise seja resolvida imediatamente e o timeout seja 0, o callback da promise (3) é executado antes do callback do timeout (4), porque a fila de microtarefas é completamente esvaziada antes da próxima macrotarefa ser executada.

Buscando Dados de uma API usando Promises

Este exemplo mostra como buscar dados de uma API remota usando promises.


javascript— editable

Encadeamento de Promises

O encadeamento de promises é um recurso poderoso que permite vincular várias operações assíncronas. Cada .then retorna uma nova promise, e o que você return de um handler se torna o valor de cumprimento dessa nova promise — é por isso que o exemplo abaixo carrega um valor por várias etapas. Para mais informações, consulte JavaScript: Promises e Encadeamento.


javascript— editable

Integrando async/await com Promises em JavaScript

Usar async/await de forma eficaz pode simplificar o tratamento de operações assíncronas, tornando seu código mais limpo e fácil de entender, mantendo todo o poder das promises JavaScript. Você aprenderá mais sobre isso em JavaScript async/await, mas aqui está um exemplo simples.


javascript— editable

Conclusão

Dominar as promises JavaScript é fundamental para qualquer desenvolvedor que queira gerenciar operações assíncronas com eficiência. Lembre-se do modelo central: uma promise está pending até que o executor chame resolve ou reject, após o que ela está settled para sempre; você lê o resultado com .then/.catch/.finally; e esses callbacks sempre são executados como microtarefas, após o código síncrono atual.

Próximos passos

Prática

Prática
O que é uma promise em JavaScript?
O que é uma promise em JavaScript?
Was this page helpful?