Los observables
1. Observables en JavaScript con la PokeAPI #
En JavaScript, los Observables son una característica proporcionada por la biblioteca RxJS (Reactive Extensions for JavaScript) que permite trabajar con flujos de datos de manera asíncrona. Un Observable es una fuente de datos que emite valores a lo largo del tiempo, y los componentes interesados (llamados observadores) pueden suscribirse para recibir esos valores.
¿Qué es un Observable? #
Un Observable es como una función que puede emitir múltiples valores a lo largo del tiempo. Los observadores se suscriben a un Observable para recibir estos valores. A diferencia de las promesas, que manejan una única respuesta asíncrona, los Observables pueden manejar múltiples eventos.
- Crear un Observable: Se puede crear un Observable que emite datos usando
new Observable()o utilizando operadores de creación proporcionados por RxJS, comofromEvent,interval, etc. - Suscribirse: Los observadores se suscriben a un Observable para recibir valores emitidos por él.
- Emitir valores: Los valores pueden ser emitidos manualmente o como resultado de eventos, promesas, etc.
Ejemplo con la PokeAPI usando RxJS #
Supongamos que queremos realizar una serie de solicitudes a la PokeAPI para obtener información sobre varios Pokémon y emitir los resultados a medida que se reciben.
Primero, necesitas instalar RxJS si no lo tienes:
1npm install rxjs
Luego, puedes escribir el siguiente código:
1import { from } from 'rxjs'; 2import { map, catchError } from 'rxjs/operators'; 3import { ajax } from 'rxjs/ajax'; 4import { of } from 'rxjs'; 5 6function obtenerPokemon(nombre) { 7 return ajax.getJSON(`https://pokeapi.co/api/v2/pokemon/${nombre}`).pipe( 8 map(data => data), 9 catchError(error => { 10 console.error('Error al obtener los datos:', error); 11 return of(null); // Devuelve un Observable con un valor nulo en caso de error 12 }) 13 ); 14} 15 16// Crear un Observable para obtener varios Pokémon 17const pokemones = ['pikachu', 'bulbasaur', 'charmander']; 18 19from(pokemones).pipe( 20 map(nombre => obtenerPokemon(nombre)) 21).subscribe(observable => { 22 observable.subscribe(pokemon => { 23 if (pokemon) { 24 console.log(`Nombre: ${pokemon.name}, Altura: ${pokemon.height}, Peso: ${pokemon.weight}`); 25 } 26 }); 27});
En este ejemplo:
obtenerPokemon(nombre): Esta función devuelve un Observable que realiza una solicitud a la PokeAPI para obtener información sobre un Pokémon.ajax.getJSONes un operador de RxJS que hace una solicitud HTTP GET y convierte la respuesta JSON en un Observable.pipese utiliza para encadenar operadores que transforman los datos o manejan errores.mapprocesa los datos del Pokémon.catchErrormaneja errores en la solicitud y devuelve un Observable con un valor nulo si ocurre un error.
from(pokemones): Crea un Observable que emite cada elemento del arraypokemones.mapdentro del Observable principal transforma cada nombre de Pokémon en un Observable que realiza la solicitud.subscribe: Los observadores se suscriben a los Observables creados para recibir los datos de cada Pokémon a medida que se obtienen.
Resultado: El código anterior realiza solicitudes a la PokeAPI para obtener información sobre Pikachu, Bulbasaur y Charmander. A medida que se reciben los datos, se imprimen en la consola.
2. Ventajas de los Observables #
- Manejo de múltiples eventos: A diferencia de las promesas, que manejan una única respuesta, los Observables pueden emitir múltiples valores a lo largo del tiempo.
- Operadores potentes: RxJS proporciona una amplia variedad de operadores que permiten manipular flujos de datos de manera compleja pero eficiente.
- Cancelación de suscripciones: Puedes cancelar una suscripción a un Observable para detener la recepción de valores, lo cual es útil para optimizar el rendimiento y evitar fugas de memoria.
Resumen del tema
Conceptos clave #
- Paradigma Reactivo (RxJS): un
Observablees un flujo continuo (stream) que emite 0, 1 o múltiples valores a lo largo del tiempo hacia observadores suscritos (.subscribe()). - Diferencia vs Promesas:
- Promesa: ansiosa (eager), emite un único valor y no es cancelable de forma nativa.
- Observable: perezoso (lazy, no se ejecuta hasta suscribirse), multidifusión/múltiples emisiones y cancelable (
subscription.unsubscribe()).
- Operadores de Tubería (
pipe): transformación y control de flujos con operadores declarativos (map,filter,mergeMap,switchMap,catchError).
Qué debes recordar #
Usa Observables cuando necesites procesar secuencias continuas de eventos o múltiples respuestas asíncronas con capacidad de cancelación y operadores reactivos.