Un observable es una colección de eventos futuros o valores que pueden ser asíncronos. Se puede pensar en ellos como flujos de datos que se pueden suscribir y manejar con diversas operaciones.
Un observer es un consumidor de los valores entregados por el observable. Define cómo se manejan los valores, los errores y la finalización de la secuencia.
Una subscription es el acto de escuchar los valores emitidos por un observable. Puedes cancelar la suscripción en cualquier momento para detener el flujo de datos.
Los operadores son funciones que permiten manipular, filtrar y transformar flujos de datos dentro de un observable. RxJS ofrece una amplia variedad de operadores que facilitan el manejo de flujos de datos complejos.
Para crear un observable en RxJS, se utiliza el constructor Observable
. A continuación, se muestra un ejemplo simple:
import { Observable } from 'rxjs';
const myObservable = new Observable(subscriber => {
subscriber.next('Hello');
subscriber.next('World');
subscriber.complete();
});
En este ejemplo, el observable emite dos valores ('Hello' y 'World') y luego se completa.
Para recibir los valores emitidos por un observable, necesitas suscribirte a él:
myObservable.subscribe({
next(x) { console.log(x); },
error(err) { console.error('Error: ' + err); },
complete() { console.log('Completed'); }
});
Esto imprimirá:
Hello
World
Completed
RxJS proporciona numerosos operadores para transformar, filtrar y combinar observables. Aquí hay algunos ejemplos comunes:
El operador map
transforma cada valor emitido por un observable aplicándole una función:
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
const numbers = of(1, 2, 3, 4, 5);
const squaredNumbers = numbers.pipe(map(x => x * x));
squaredNumbers.subscribe(x => console.log(x));
Esto imprimirá:
1
4
9
16
25
El operador filter
permite filtrar los valores emitidos por un observable basado en una condición:
import { of } from 'rxjs';
import { filter } from 'rxjs/operators';
const numbers = of(1, 2, 3, 4, 5);
const evenNumbers = numbers.pipe(filter(x => x % 2 === 0));
evenNumbers.subscribe(x => console.log(x));
Esto imprimirá:
2
4
El operador merge
combina múltiples observables en uno solo, emitiendo los valores a medida que se generan:
import { of, merge } from 'rxjs';
const observable1 = of('Hello');
const observable2 = of('World');
const merged = merge(observable1, observable2);
merged.subscribe(x => console.log(x));
Esto imprimirá:
Hello
World
A continuación, se muestra un ejemplo más complejo que utiliza observables para manejar eventos de usuario en una página web:
import { fromEvent } from 'rxjs';
import { map, throttleTime } from 'rxjs/operators';
// Seleccionar el elemento
const button = document.querySelector('button');
// Crear un observable de eventos de clic
const clicks = fromEvent(button, 'click');
// Transformar el evento de clic para obtener la posición del clic y limitar la frecuencia
const positions = clicks.pipe(
throttleTime(1000),
map(event => ({ x: event.clientX, y: event.clientY }))
);
// Suscribirse y manejar los eventos
positions.subscribe(pos => {
console.log(`Clicked at: ${pos.x}, ${pos.y}`);
});
En este ejemplo, cada clic en el botón se registra, pero solo uno cada segundo, y se registra la posición del clic en la consola.
RxJS y su concepto de observables proporcionan una forma poderosa y flexible de manejar flujos de datos asíncronos en JavaScript. Al aprender a utilizar observables y los diversos operadores que RxJS ofrece, puedes escribir código más limpio, eficiente y fácil de mantener para aplicaciones que dependen de eventos y operaciones asíncronas.
Jorge García
Fullstack developer