Implementando chamadas de API Repetitivas Polling com RxJS

Implementando chamadas de API Repetitivas Polling com RxJS

No desenvolvimento de aplicativos front-end, buscar dados do back-end é uma tarefa recorrente. O processo geralmente envolve chamar uma API, processar a resposta e exibir os dados na página. Esse fluxo de trabalho é comum em sistemas que dependem de atualizações frequentes, como dashboards em tempo real, monitoramento de status ou trilhas de eventos.

No entanto, alguns casos de uso exigem uma comunicação cliente-servidor mais sofisticada, como chamadas de API repetitivas (conhecidas como polling). Neste artigo, vamos explorar como implementar esse padrão utilizando o RxJS.

Revisão do RxJS: Fundamentos da Programação Reativa

Antes de mergulharmos na implementação de polling com o RxJS, é importante recapitular alguns conceitos fundamentais dessa biblioteca. O RxJS (Reactive Extensions for JavaScript) traz os princípios da programação reativa para o JavaScript, oferecendo uma abordagem mais flexível para gerenciar eventos assíncronos, fluxos de dados e operações de tempo.

Conceitos-Chave:

  • Observable: Um Observable é uma fonte de dados que emite valores ao longo do tempo. Ele pode ser assinado por um ou mais Observers, que recebem os valores emitidos para tomar ações com base nesses dados. 
  • Observer: Um Observer é um objeto que assina um Observable e define como lidar com as notificações enviadas (valores ou eventos). Ele contém três métodos principais: next() para novos valores, error() para falhas e complete() quando o fluxo termina.
  • Subject: Um Subject é um tipo especial de Observable que permite que valores sejam emitidos para múltiplos Observers simultaneamente. Isso o torna útil em cenários onde vários assinantes precisam receber atualizações a partir de uma única fonte de dados.
  • Operators: São funções aplicadas a Observables que podem transformar, filtrar ou combinar fluxos de dados. Exemplos comuns de operadores incluem map(), filter(), switchMap(), debounceTime(), entre outros. Esses operadores nos ajudam a manipular fluxos de dados de forma eficiente e precisa.

Agora que revisitamos os conceitos básicos, vamos explorar como usá-los para implementar o polling de uma API.

O Que é Polling?

O polling é uma técnica usada para consultar repetidamente uma API ou outro serviço para verificar atualizações de dados em intervalos regulares. Isso é útil quando não há suporte para WebSockets ou notificações push, e você ainda precisa atualizar periodicamente os dados exibidos no cliente.

No entanto, uma das principais preocupações com o polling é evitar sobrecarregar o servidor com solicitações desnecessárias ou realizar muitas chamadas quando os dados não mudaram. A abordagem reativa do RxJS nos oferece uma solução mais elegante para implementar esse padrão.

Implementando Polling com RxJS

Vamos imaginar que temos uma API que retorna o status de um processo, e precisamos exibir essas informações em nosso aplicativo, atualizando-as a cada intervalo de tempo definido.

Aqui está uma implementação simples utilizando RxJS:

import { interval } from 'rxjs';
import { switchMap, takeUntil } from 'rxjs/operators';
import { ajax } from 'rxjs/ajax';

// Função que faz a chamada à API
const fetchProcessStatus = () => {
return ajax.getJSON('/api/process/status'); // Faz a solicitação à API
};

// Polling com RxJS
const polling$ = interval(5000) // Define o intervalo de 5 segundos
.pipe(
switchMap(() => fetchProcessStatus()), // Chama a API a cada intervalo
takeUntil(stopPolling$) // Define uma condição para parar o polling
);

// Assinatura do Observable
polling$.subscribe(
(data) => {
console.log('Status atualizado:', data); // Processa os dados retornados pela API
},
(error) => {
console.error('Erro na chamada da API:', error); // Trata erros
}
);

Explicação do Código:

  • interval(5000): Utilizamos o operador interval() para criar um fluxo de dados que emite valores a cada 5 segundos. Esse intervalo define a frequência do polling.
  • switchMap(): O operador switchMap() é usado para transformar cada valor emitido pelo interval() em uma chamada para a API. Isso significa que a cada 5 segundos, uma nova solicitação será feita. Se uma solicitação ainda estiver em andamento quando o próximo intervalo ocorrer, ela será cancelada e a nova será iniciada. 
  • takeUntil(stopPolling$): O takeUntil() nos permite definir uma condição que interrompe o polling. Por exemplo, podemos parar o polling se o processo terminar ou se o usuário sair da página.
  • fetchProcessStatus(): Essa função encapsula a chamada da API usando o ajax.getJSON() do RxJS, que retorna um Observable representando a resposta da API.

Técnicas Avançadas de Polling

1. Polling Adaptativo

Em alguns casos, pode ser interessante ajustar dinamicamente o intervalo entre as chamadas, dependendo do estado da resposta. Por exemplo, se o processo ainda estiver "em andamento", podemos aumentar o intervalo para 10 segundos. Caso o processo esteja prestes a terminar, podemos reduzir o intervalo para consultar mais frequentemente.

const adaptivePolling$ = interval(5000).pipe(
switchMap(() => fetchProcessStatus()),
tap(response => {
// Se o status for 'em andamento', aumentar o intervalo
if (response.status === 'in_progress') {
polling$.unsubscribe(); // Cancela o polling atual
interval(10000).subscribe(); // Inicia novo polling com intervalo maior
}
}),
takeUntil(stopPolling$)
);

2. Polling com Backoff Exponencial

Outra técnica comum é o backoff exponencial, onde o intervalo entre as solicitações aumenta gradualmente após falhas, reduzindo a pressão sobre o servidor e dando tempo para a recuperação. O RxJS facilita a implementação disso usando o operador retryWhen():

import { of } from 'rxjs';
import { retryWhen, delay, scan } from 'rxjs/operators';

polling$.pipe(
retryWhen(errors => errors.pipe(
scan((acc, error) => {
if (acc >= 3) throw error; // Após 3 tentativas falhas, lançar o erro
return acc + 1;
}, 0),
delay(2000) // Aumenta o intervalo entre as tentativas
))
).subscribe();

Neste exemplo, o polling será tentado novamente três vezes após falhas, com um intervalo crescente entre as tentativas.

Considerações Finais

A técnica de polling continua sendo relevante em muitos cenários, principalmente quando não há suporte para tecnologias como WebSockets ou Server-Sent Events. Com o RxJS, podemos implementar polling de forma eficiente, lidando com operações assíncronas de forma clara e controlada.

A chave para um polling eficiente é equilibrar a frequência das chamadas e a carga no servidor, garantindo que o usuário obtenha atualizações rápidas, mas sem sobrecarregar o sistema. Operadores como switchMap(), retryWhen() e takeUntil() tornam o RxJS uma excelente escolha para construir soluções de polling robustas, especialmente em aplicativos que demandam alta reatividade.

Em projetos que exigem atualizações constantes e rápidas, o uso adequado de polling pode ser a solução ideal, evitando a complexidade e os desafios de outras tecnologias.

Conteúdo Relacionado

Zurück zum Blog

Hinterlasse einen Kommentar

Bitte beachte, dass Kommentare vor der Veröffentlichung freigegeben werden müssen.