Retentativa com Await

Construindo Robustez em Funções Assíncronas JavaScript

Na busca por aplicações JavaScript mais resilientes, o padrão de retentativa (retry) surge como um aliado poderoso, especialmente quando combinado com o elegante async/await. Este artigo explora como implementar retentativas em funções assíncronas, focando na clareza e na robustez.


O Problema: Falhas Inesperadas

Em ambientes dinâmicos, falhas são inevitáveis. Uma requisição de rede pode falhar, um serviço externo pode estar indisponível, ou um recurso pode estar temporariamente bloqueado. Nesses cenários, interromper a execução abruptamente pode comprometer a experiência do usuário e a integridade da aplicação.

A Solução: Retentativa com async/await

O padrão de retentativa permite que uma função assíncrona tente novamente executar uma operação que falhou, um número predefinido de vezes, antes de desistir. O async/await simplifica a implementação desse padrão, tornando o código mais legível e fácil de manter.

Exemplo Prático

Considere a seguinte função assíncrona, que grava dados de localização em um serviço externo:

async function saveLocation(source) {
  const maxRetries = 3;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      await gravaLatLng(12996334, source);
      return; // Sai da função se a execução for bem-sucedida
    } catch (e) {
      console.error(`Tentativa ${attempt} falhou: ${e.message}`);
      if (attempt === maxRetries) {
        console.error("Número máximo de tentativas excedido.");
        throw e; // Lança o erro após todas as tentativas falharem
      }
      // Opcional: Adicione um atraso antes de tentar novamente
      await new Promise(resolve => setTimeout(resolve, 1000)); // Espera 1 segundo
    }
  }
}

Neste exemplo:

  • maxRetries define o número máximo de tentativas.

  • O loop for itera até o número máximo de tentativas.

  • O bloco try executa a operação assíncrona gravaLatLng.

  • Se a operação for bem-sucedida, a função retorna.

  • Se a operação falhar, o bloco catch captura o erro, registra-o e verifica se o número máximo de tentativas foi atingido.

  • Se o número máximo de tentativas não foi atingido, a função espera um segundo antes de tentar novamente.

Benefícios

  • Resiliência: A aplicação se torna mais tolerante a falhas transitórias.

  • Melhoria na experiência do usuário: A aplicação pode se recuperar de falhas sem interromper a execução.

  • Código mais limpo: O async/await torna a implementação do padrão de retentativa mais legível.

Considerações

  • Estratégia de retentativa: É importante definir uma estratégia de retentativa adequada, considerando o tipo de falha e o impacto na aplicação.

  • Exponencial Backoff: Em alguns casos, pode ser interessante aumentar o tempo de espera entre as tentativas de forma exponencial.

  • Tratamento de erros: É fundamental tratar os erros adequadamente, registrando-os e informando o usuário quando necessário.

Conclusão

O padrão de retentativa com async/await é uma ferramenta poderosa para construir aplicações JavaScript mais robustas e resilientes. Ao lidar com falhas de forma elegante, podemos garantir uma experiência do usuário mais suave e confiável.