Leodario.com

Leodario.com – Tudo sobre Tecnologia

Aula 8 – API JavaScript, Node.js e Express – Promises Fundamentals – Programação assíncrona

Imagem destacada da aula de API

Introdução (3 min)

Imagine pedir um café em uma cafeteria movimentada. Você não fica parado esperando o barista preparar seu pedido, bloqueando toda a fila, certo? Você recebe um número e continua fazendo outras coisas até que seu café esteja pronto. Promises em JavaScript funcionam de forma semelhante. Elas permitem que seu código continue executando outras tarefas enquanto aguarda operações assíncronas, como requisições a APIs ou leitura de arquivos, sem travar a aplicação.

Este mecanismo é fundamental para APIs modernas, pois garante responsividade e uma melhor experiência do usuário. Nesta aula, vamos construir uma base sólida sobre Promises, implementando exemplos práticos que rodam em um ambiente Node.js/Express, compatível com o HostGator Plano M.

No contexto Node.js/Express, Promises são essenciais para lidar com operações de I/O não bloqueantes, como acesso a bancos de dados e chamadas a APIs externas, mantendo a performance e a escalabilidade da sua aplicação.

Conceito Fundamental (7 min)

Uma Promise representa o resultado eventual de uma operação assíncrona. Ela pode estar em um dos três estados:

    • Pending (pendente): Estado inicial, a operação ainda está em andamento.
    • Fulfilled (resolvida): A operação foi concluída com sucesso, e a Promise possui um valor resultante.
    • Rejected (rejeitada): A operação falhou, e a Promise possui um motivo para a falha (geralmente um erro).

Em aplicações reais, Promises são usadas para gerenciar requisições HTTP, operações de leitura/escrita em disco, interações com bancos de dados, e muito mais. Elas se integram perfeitamente com tecnologias como async/await, simplificando o código assíncrono.

A principal vantagem das Promises é a capacidade de encadear operações assíncronas de forma limpa e legível, evitando o “callback hell”. A desvantagem é que elas adicionam uma pequena complexidade inicial para desenvolvedores acostumados com código síncrono.

Implementação Prática (10 min)

// Simulando uma requisição a uma API com um timeout
function buscarDados(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const sucesso = Math.random() < 0.8; // 80% de chance de sucesso
      if (sucesso) {
        const dados = { mensagem: 'Dados obtidos com sucesso!', url };
        resolve(dados); // Operação bem-sucedida
      } else {
        const erro = new Error('Falha ao obter dados.');
        reject(erro); // Operação falhou
      }
    }, 1000); // Simulando um delay de 1 segundo
  });
}

// Usando a Promise buscarDados('https://meusite.com/api/dados') .then((dados) => { console.log('Sucesso:', dados); // Lidando com o sucesso }) .catch((erro) => { console.error('Erro:', erro); // Lidando com a falha });

// Encadeando Promises buscarDados('https://meusite.com/api/dados') .then((dados) => { console.log('Primeiro sucesso:', dados); return buscarDados('https://meusite.com/api/outrosdados'); // Retornando outra Promise }) .then((outrosDados) => { console.log('Segundo sucesso:', outrosDados); }) .catch((erro) => { console.error('Erro em algum ponto:', erro); // Captura erros em qualquer etapa });

Este código simula uma requisição a uma API usando setTimeout. A função buscarDados retorna uma Promise. Usamos .then para lidar com o sucesso e .catch para lidar com falhas. O exemplo demonstra também o encadeamento de Promises, onde o resultado de uma é usado na próxima.

Exercício Hands-On (5 min)

Crie uma função verificarStatusDoServidor(url) que retorna uma Promise. A Promise deve resolver com “Servidor online” se a URL responder em menos de 500ms, e rejeitar com “Tempo limite excedido” caso contrário.

Solução:

function verificarStatusDoServidor(url) {
  return new Promise((resolve, reject) => {
    const timeoutId = setTimeout(() => {
      reject(new Error('Tempo limite excedido'));
    }, 500);

fetch(url) // Usando fetch para uma requisição real (requer um servidor rodando) .then(() => { clearTimeout(timeoutId); // Cancela o timeout se a requisição for bem-sucedida resolve('Servidor online'); }) .catch((erro) => { clearTimeout(timeoutId); reject(erro); // Rejeita com o erro original se a requisição falhar }); }); }

verificarStatusDoServidor('http://localhost:3000') // Substitua pela URL do seu servidor .then(console.log) .catch(console.error);

Para testar, você precisa de um servidor rodando localmente (como um servidor Express básico). Substitua http://localhost:3000 pela URL correta. Você pode usar ferramentas como curl ou o navegador para verificar se o servidor está respondendo.

Próximos passos: explore async/await para simplificar ainda mais o código assíncrono e aprofunde-se no tratamento de erros com Promises.

🚀 Pronto para a próxima aula?

Continue sua jornada no desenvolvimento de APIs e domine Node.js & Express!

📚 Ver todas as aulas