RxJS sem medo: Observables no Angular

RxJS sem medo: Observables no Angular

Robson Rabelo - 12 de julho de 2026 - 0 visualizações

Observable é a Promise que continua: os 6 operadores que resolvem 90% do dia a dia, o typeahead correto em 5 linhas, o vazamento clássico e a convivência com Signals.

Pergunte a qualquer dev Angular o que mais assustou no início, e a resposta é quase unânime: RxJS. Observables, operadores com nomes estranhos, switchMap versus mergeMap... A má notícia: RxJS está no coração do Angular (HTTP, rotas, formulários emitem Observables). A boa: 90% do uso real cabe em meia dúzia de conceitos, e este artigo é exatamente esse recorte.

Observable: a Promise que continua

Uma Promise entrega um valor, uma vez. Um Observable é um fluxo: pode emitir zero, um ou mil valores ao longo do tempo: cada tecla digitada, cada mudança de rota, cada mensagem do WebSocket (rxjs.dev).

// Promise: um valor e acabou
const user = await http.get("/api/user");

// Observable: um fluxo que você assina
busca.valueChanges.subscribe((termo) => console.log(termo));
// emite a CADA mudança do campo, para sempre (até o unsubscribe)

A segunda diferença crucial: Observables são preguiçosos e canceláveis. Nada acontece até alguém assinar, e a assinatura pode ser cancelada, inclusive no meio de uma requisição HTTP. É essa propriedade que resolve elegantemente o bug clássico do "resultado da busca antiga chegou depois da nova".

Os 6 operadores que resolvem 90% do dia a dia

Operadores transformam fluxos como funções de array transformam listas, encadeados no pipe():

resultados$ = this.busca.valueChanges.pipe(
  debounceTime(300),          // espera o usuário parar de digitar
  distinctUntilChanged(),     // ignora se o termo não mudou
  switchMap((termo) =>        // cancela a busca anterior e faz a nova
    this.api.buscar(termo).pipe(
      catchError(() => of([])) // erro não mata o fluxo: devolve vazio
    )
  )
);

Cinco linhas que implementam um typeahead correto: com debounce, deduplicação, cancelamento de requisição obsoleta e tolerância a erro. Fazer o mesmo "na mão" com flags e timeouts é uma tarde de bugs.

O kit essencial: map (transforma cada valor), filter (deixa passar alguns), debounceTime (espera silêncio), distinctUntilChanged (ignora repetido), switchMap (troca para outro fluxo, cancelando o anterior: o certo para buscas), catchError (trata sem matar o fluxo).

E a pegadinha nomeada: para buscas, use switchMap (só a última importa); para salvamentos, use concatMap (nenhum pode ser cancelado, ordem importa). Confundir os dois é o bug silencioso mais comum de RxJS.

O fluxo de um typeahead com RxJS

O vazamento clássico (e a solução de uma palavra)

Todo subscribe() manual cria uma assinatura que vive até ser cancelada. Componente destruído com assinatura viva = vazamento: callbacks rodando sobre componentes mortos, memória crescendo, bugs fantasmas.

A solução preferida não é lembrar de dar unsubscribe (ninguém lembra); é não assinar manualmente: o async pipe assina e cancela sozinho, alinhado ao ciclo de vida:

<ul>
  <li *ngFor="let p of resultados$ | async">{{ p.nome }}</li>
</ul>

Regras da casa que evitam a categoria inteira de bugs: async pipe por padrão; quando o subscribe manual for inevitável, takeUntilDestroyed() (Angular 16+) fecha o fluxo na destruição do componente.

E os Signals, substituem o RxJS?

A resposta curta: dividem o trabalho. Signals (tema do próximo artigo) são o novo padrão para estado síncrono da UI; RxJS continua sendo a ferramenta para eventos assíncronos ao longo do tempo: HTTP com cancelamento, websockets, debounce, combinação de fontes. O próprio Angular fornece a ponte (toSignal/toObservable): o fluxo complexo vive em RxJS, o template consome um signal simples. A direção oficial é essa convivência (angular.dev).

O checklist do RxJS saudável

  • async pipe no template; subscribe manual só com takeUntilDestroyed.
  • switchMap para buscas, concatMap para gravações.
  • catchError dentro do fluxo interno (para o stream principal sobreviver ao erro).
  • Lógica de fluxo em services (testável), componente magro consumindo.
  • Se o encadeamento passou de ~5 operadores, extraia e nomeie pedaços: legibilidade continua sendo a otimização que mais paga.

Formar times Angular nesse recorte pragmático de RxJS (o que usar, o que ignorar, como testar) é parte do nosso serviço de Desenvolvimento Web, Mobile e Desktop.

Tem um encadeamento RxJS que ninguém no time entende? Cole-o na conversa com a IA da Rabelo Digital, aqui no canto da tela, e ela traduz operador por operador. Sem formulário, sem espera.


Leia também

Compartilhar:

Deixe um Comentário

Categorias

Posts Recentes