Fundamento del patrón Observer
El patrón de diseño Observer describe un comportamiento de tipo publicador-suscribidor: un objeto (conocido como Subject u Observable) mantiene una lista de dependencias llamadas Observers o suscriptores y les notifica de forma automática cualquier cambio de estado o emisión de datos.
Observables vs Promesas (Promises)
Una Promesa representa un valor único que se resolverá en el futuro y es eager: se ejecuta de inmediato al crearse. Un Observable, en cambio, representa un flujo de múltiples valores a lo largo del tiempo y es lazy: no emite nada hasta que alguien se suscribe explícitamente.
Ciclo de vida de un Observable
Un Observable gestiona tres canales de comunicación con sus suscriptores:
- next(): Emite un nuevo valor o paquete de datos hacia el flujo.
- error(): Notifica que ocurrió una excepción e interrumpe definitivamente la ejecución del flujo.
- complete(): Indica que el flujo ha terminado de emitir datos y cierra el canal de forma limpia.
Implementación conceptual básica en JavaScript puro
class Observable {
constructor(setupFunction) {
this.setupFunction = setupFunction;
}
subscribe(observer) {
// El observable se ejecuta unicamente cuando alguien se suscribe (Lazy)
return this.setupFunction(observer);
}
}
// Uso del Observable
const streamNumerico = new Observable((observer) => {
let contador = 0;
const intervalo = setInterval(() => {
observer.next(contador++);
if (contador > 3) {
observer.complete();
clearInterval(intervalo);
}
}, 1000);
// Funcion de limpieza (Teardown logic)
return () => clearInterval(intervalo);
});
Gestión de memoria y desuscripción
Un error habitual con flujos asíncronos es olvidar cancelar las suscripciones (unsubscribe). Eso genera fugas de memoria severas (memory leaks), porque mantenemos referencias activas a componentes que ya no están visibles en el DOM.
Preguntas clave
- ¿Cuál es la diferencia de comportamiento en la ejecución (eager vs lazy) entre una Promesa nativa y un Observable?
- ¿Por qué la gestión de funciones de limpieza (teardown logic) dentro de las suscripciones es crítica para prevenir fugas de memoria en aplicaciones complejas?
© Arturo Juárez Monroy