Programação assíncrona com Promises
O Javascript ES6 introduziu o conceito de Pomisses para pedidos assíncronos feitos a um servidor.
Antes de haver Promisses, as respostas com dados do servidor eram recebidas numa função de callback. Tal, no entanto, poderia levar a situações confusas que as Promisses vieram obviar.
O que é uma Promisse ? Uma Promisse é um contentor para um valor que chegará no futuro. É uma promessa, tal como na vida real.
Podemos criar Promisses e/ou consumir Promisses.
Modo de funcionamento das Promises
Primeiro que tudo, uma Promisse é um objeto. Uma Promisse possui 3 estados:
- Pending: estado inicial da Promisse antes de ser bem sucedida ou falhar
- Resolved: Promisse completa e bem sucedida
- Rejected: Promisse falhada

Quando solicitamos dados do servidor usando uma Promisse, ele ficará no estado pendente (pending) até recebermos os dados.
Se conseguirmos obter as informações do servidor, a Promisse será resolvida com sucesso e passará ao estado resolved. Mas se não obtivermos as informações, a Promisse ficará no estado rejeitado (rejected).
Criação de Promises
Para construirmos uma Promise, e dado que uma Promise é um objeto, usamos o construtor da Promise. Este construtor aceita como argumento uma função com dois parâmetros:
resolve e reject que são referências para funções .
const myPromise = new Promise((resolve, reject) => {
let condition;
if(condition is true) {
resolve('Promise is resolved successfully.');
} else {
reject('Promise is rejected');
}
});
Na Promise, excutamos uma tarefa qualquer. Se a tarefa f0r bem sucedida, chamamos a função resolve(). Por exemplo, se a tarefa for obter dados do servidor, e for bem sucedida, chamamos a função resolve() passando-lhe os dados. Se a tarefa não for bem sucedida chamamos a função reject() com um código de erro ou uma mensagem de erro.
Consumo de Promises
Uma Promise é um objeto. Esse objeto possui os métodos: then() e catch().
O método then() é chamado quando, na origem, a Promise é bem sucedida e passa para o estado resolved.
O método catch() é chamado quando, na origem, a Promise é mal sucedida e passa para o estado rejected.
Se acedermos a um serviço que retorna uma Promise, basicamente, temos de tomar ações nesses dois métodos.
Exemplo:
const promise = service.findAll();
promise.then((dados) => {
let html = "";
dados.forEach(
(dado) => (html += `<tr><td>${dado.name}</td><td>${rate.years}</td><td>${dado.rate}% </td></tr>`)
);
document.getElementById("dados").innerHTML = html;
})
.catch((e) => console.log(e));
Neste exemplo, acedemos ao método findAll() de um qualquer serviço na web, para obter dados. O método findAll(), retorna uma Promise. Se a Promise tiver sido bem sucedida, ou seja, estiver no estado resolved, o método then() da Promise será chamado e, nesse método, mostramos os dados na página. Se a Promise não tiver sido bem sucedida, ou seja, estiver o estado rejected, o método catch() da Promise será chamado com um erro, e mostramos esse erro na consola.
Async/Await
O Javascript ES6 introduziu uma melhoria sintática significativa no consumo de Promises. Trata-se das instruções Async/Await. O Async/Await permite-nos escrever código assíncrono como se estivéssemos a escrever código sincrono.
Async/Await funciona da seguinte maneira: temos uma função de javascript na qual iremos fazer um pedido assíncrono para obtermos dados numa Promise. Essa função é decorada com a palavra reservada async.
Quando fazemos o pedido, dado que é um pedido assíncrono, os dados serão obtidos algures no futuro. Enquanto os dados não são recebidos, a palavra reservada await faz com que o fluxo do programa bloqueie nesse ponto, até os dados chegarem. Quando os dados chegam, são recebidos numa variável ou constante.
Devemos reter o seguinte:
Sempre que usamos uma instrução com await, essa instrução deve estar numa função decorada com async !
De notar que quando consumimos uma Promise com async/await devemos envolver o código na função async num bloco try/catch. O código sai pelo bloco catch caso a Promise seja rejeitada.
Um exemplo simples em JavaScript de consumo de Promises usando async/await seria algo assim:
// Função que simula uma operação assíncrona retornando uma Promise
function obterDados() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const sucesso = true; // altere para false para simular erro
if (sucesso) {
resolve("Dados recebidos com sucesso!");
} else {
reject("Houve um erro na obtenção dos dados.");
}
}, 2000); // simula atraso de 2 segundos
});
}
// Função assíncrona que consome a Promise usando async/await
async function pesquisarDados() {
try {
console.log("A obter dados...");
const resultado = await obterDados(); // aguarda a Promise
console.log(resultado);
} catch (erro) {
console.error("Erro:", erro);
}
}
// Executa a função
pesquisarDados();
O código:
- Cria uma função
obterDadosque retorna uma Promise. - A função
pesquisarDadosutilizaasync/awaitpara esperar o resultado da promessa. - O bloco
try/catchtrata erros de forma semelhante ao código síncrono.
