Angular 21 de Cero a Experto / RxJS y observables a gran escala
Operadores y pipe: transformar el stream
Un Observable en crudo rara vez es lo que quieres: quieres mapear sus valores, filtrar los que
no sirven, o esperar a que el usuario deje de escribir antes de reaccionar. Los OPERADORES son
funciones que transforman un stream en otro, y pipe los encadena como una tubería. Hoy
dominas los operadores esenciales —map, filter, tap, debounceTime— y entiendes por qué
pipe se lee como una línea de montaje.
La línea de montaje
pipe: encadenar operadores
pipe recibe operadores y los aplica en orden, devolviendo un Observable nuevo:
import { of, map, filter } from 'rxjs';
of(1, 2, 3, 4, 5).pipe(
filter((n) => n % 2 === 0), // deja pasar solo los pares: 2, 4
map((n) => n * 10), // los multiplica: 20, 40
).subscribe((v) => console.log(v)); // imprime 20, luego 40El orden importa: filter antes que map filtra los originales; al revés, mapearía todos y
filtraría los resultados. Cada operador recibe el stream de arriba y produce uno nuevo —nunca
muta el original—.
Los operadores esenciales
El caso estrella: una búsqueda en vivo
Este pipeline es el "hola mundo" de RxJS —y demuestra por qué existe—:
import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs';
// this.buscador es un FormControl; valueChanges es su Observable
this.buscador.valueChanges.pipe(
map((texto) => (texto ?? '').trim()), // limpia
filter((texto) => texto.length >= 2), // ignora búsquedas muy cortas
debounceTime(300), // espera a que el usuario pare de teclear
distinctUntilChanged(), // ignora si el término no cambió
).subscribe((termino) => this.buscar(termino));Sin RxJS, esto serían varios setTimeout, banderas y comparaciones a mano. Con operadores, es
una tubería declarativa que se lee como una frase: "limpia, ignora lo corto, espera 300ms tras
la última tecla, ignora repeticiones, y busca". El debounceTime solo evita decenas de
peticiones inútiles mientras el usuario escribe.
Pruébalo: tu propio map y filter en un stream
Los operadores son funciones que envuelven un Observable y devuelven otro. Aquí, un mini-RxJS
con map y filter sobre tu Observable, en vivo:
Observa cómo cada operador (map, filter) toma la fuente y devuelve un Observable NUEVO que,
al recibir un valor, lo transforma o filtra antes de reenviarlo. pipe solo los encadena con
un reduce. Es exactamente el mecanismo de RxJS: operadores puros que se componen, sin mutar
el stream original. La misma composición de funciones del SC-02, sobre valores en el tiempo.
¿Para qué sirve `debounceTime(300)` en una búsqueda en vivo?
Mini-reto
En el playground, añade dos operadores a tu mini-RxJS: 1) tap(fn) que ejecute un efecto
(un console.log) sin alterar el valor y lo reenvíe; 2) take(n) que emita solo las primeras
n emisiones y complete. Encadénalos en un pipe con map y filter, y verifica el orden de
ejecución. Piensa qué cambia si pones tap antes o después del map.
Qué sigue
Ya transformas un stream de valores simples. Pero ¿qué pasa cuando cada valor del stream
dispara OTRO Observable —un término de búsqueda que dispara una petición HTTP—? Eso es un
"higher-order observable", y su manejo (con switchMap) es una de las partes más importantes
—y sutiles— de RxJS. La próxima lección.