Como Adicionar Timeout em Promises JavaScript com Promise.race

Como Adicionar Timeout em Promises JavaScript com Promise.race

Requisições assíncronas sem tempo limite de resposta podem travar o fluxo da aplicação e deixar o usuário esperando indefinidamente. Encapsular qualquer Promise em uma função de timeout usando Promise.race() resolve esse problema, cancelando o fluxo lógico e lançando um erro caso a operação exceda o tempo máximo estipulado.

JavaScript

/**
 * Adiciona um tempo limite máximo para a resolução de uma Promise.
 * @param {Promise<any>} promessa - A Promise original a ser executada.
 * @param {number} tempoMs - O tempo limite em milissegundos.
 * @returns {Promise<any>} A promessa resolvida ou uma rejeição por timeout.
 */
function comTimeout(promessa, tempoMs) {
  // Cria uma Promise que é rejeitada automaticamente após decorrido o tempo limite
  const timeout = new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error(`A operação excedeu o tempo limite de ${tempoMs}ms.`));
    }, tempoMs);
  });

  // Retorna a primeira Promise que for resolvida ou rejeitada
  return Promise.race([promessa, timeout]);
}

// --- Exemplo Prático de Uso ---
// Simula uma requisição lenta que demora 3 segundos para responder
const requisicaoLenta = new Promise((resolve) => {
  setTimeout(() => resolve('Dados recebidos do servidor!'), 3000);
});

// Tenta executar a requisição com um limite rigoroso de 1,5 segundos (1500ms)
comTimeout(requisicaoLenta, 1500)
  .then((resultado) => console.log('Sucesso:', resultado))
  .catch((erro) => console.error('Falha:', erro.message));

Pontos-chave

  • Funcionamento do Promise.race(): Executa as Promises concorrentemente e assume o resultado da primeira que for finalizada, descartando o retorno das demais.
  • Atenção a Side Effects: O Promise.race() interrompe a espera na aplicação, mas não cancela a execução interna da Promise original (como um fetch em andamento); para cancelar requisições HTTP, utilize AbortController.
  • Tratamento de Exceções: Lançar uma instância de Error dentro da Promise de timeout permite capturar a falha de forma limpa em blocos try/catch ou no .catch().
  • Reutilização Universal: A função é genérica e aceita qualquer operação assíncrona baseada em Promises, como consultas a bancos de dados, chamadas de API ou leitura de arquivos.

Thales de Oliveira Gomes

Thales de Oliveira Gomes é gestor de Tecnologia da Informação, especialista em infraestrutura de redes, computação em nuvem e operações de TI hospitalar, com mais de 18 anos de experiência na área. Graduado em Gestão de TI e pós-graduado em Engenharia de Redes e Telecomunicações, Cloud Computing, Redes de Computadores e Gestão Hospitalar, construiu uma trajetória sólida liderando projetos de alta complexidade, como a implementação e migração para nuvem de sistemas ERP de grande porte. Sua atuação no setor o levou a ser indicado ao prêmio IT Leaders Brasil na categoria Rising Leaders. Além da carreira corporativa e da paixão por tecnologia, Thales é autor independente com mais de 70 obras publicadas sobre redes, segurança da informação, Linux e física, além de criador de conteúdo no blog Vetor Tech e na plataforma CiberDicas. No universo das artes e do entretenimento, atua como produtor de música eletrônica sob o projeto Yknex, cria ilustrações digitais e compartilha walkthroughs de games no YouTube.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *