Programação Reativa em TypeScript: guia completo de RxJS
Programação reativa é um paradigma de desenvolvimento focado em fluxos de dados assíncronos e propagação de mudanças. No ecossistema TypeScript, a ferramenta mais poderosa para implementar esse paradigma é a biblioteca RxJS (Reactive Extensions for JavaScript). RxJS permite trabalhar com eventos, requisições assíncronas e estados de aplicação como sequências de dados que podem ser transformadas, combinadas e filtradas usando operadores declarativos.
Conceitos principais do RxJS
Na base do RxJS estão três entidades-chave:
- Observable — fonte de dados que pode gerar valores ao longo do tempo. Análogo a um array, mas os elementos aparecem de forma assíncrona.
- Observer — consumidor de dados que reage a três tipos de eventos:
next(novo valor),error(erro) ecomplete(finalização do fluxo). - Subscription — objeto que representa a execução de um Observable. Permite cancelar a inscrição e liberar recursos.
import { Observable } from 'rxjs';
const observable = new Observable<number>(subscriber => { subscriber.next(1); subscriber.next(2); subscriber.next(3); setTimeout(() => { subscriber.next(4); subscriber.complete(); }, 1000);});
const subscription = observable.subscribe({ next: (value) => console.log(`Recebido: ${value}`), error: (err) => console.error(`Erro: ${err}`), complete: () => console.log('Fluxo finalizado')});
// Cancelar inscrição após 500 mssetTimeout(() => subscription.unsubscribe(), 500);Operadores RxJS: base das transformações reativas
Operadores são funções puras que recebem um Observable e retornam um novo Observable, sem modificar o original. Eles são divididos em várias categorias:
- Criação:
of,from,interval,fromEvent - Transformação:
map,pluck,scan,buffer - Filtragem:
filter,take,skip,distinctUntilChanged - Combinação:
merge,concat,combineLatest,zip - Tratamento de erros:
catchError,retry,retryWhen
import { fromEvent, interval } from 'rxjs';import { map, filter, debounceTime, distinctUntilChanged } from 'rxjs/operators';
// Exemplo: busca reativa com debounceconst searchInput = document.getElementById('search') as HTMLInputElement;const input$ = fromEvent(searchInput, 'input').pipe( map(event => (event.target as HTMLInputElement).value), filter(text => text.length >= 3), debounceTime(300), distinctUntilChanged());
input$.subscribe(searchTerm => { console.log(`Busca: ${searchTerm}`); // Executar requisição HTTP});Subject: fluxos quentes e frios
Subject é um tipo especial de Observable que é simultaneamente um observador e um observável. Ele permite multicasting (distribuir) o mesmo valor para múltiplos inscritos. Principais variações:
Subject— básico, transmite apenas novos valoresBehaviorSubject— armazena o último valor e o emite para novos inscritosReplaySubject— armazena em buffer os N últimos valoresAsyncSubject— emite apenas o último valor após a finalização do fluxo
import { BehaviorSubject } from 'rxjs';
// Gerenciamento de estado da aplicação