Implementando map como operador en Observables
Feb 24, 2022

Implementando map como operador en Observables

🌟 Implementando map como Operador en Observables 🌟

En este post, vamos a explorar cómo aumentar el número de operadores que podemos implementar y usar dentro de un Observable 📈. Primero, recordemos cuál es la definición más pura de un observable con una función generadora de observables a partir de eventos:

// Define la clase "Observable"
class Observable {
  // Constructor de la clase "Observable" que acepta un argumento "subscribe"
  constructor(subscribe) {
    // Asigna el valor del argumento "subscribe" a la propiedad "_subscribe" del objeto
    this._subscribe = subscribe;
  }
  // Método "subscribe" que acepta un objeto "observer"
  subscribe(observer) {
    // Llama a la función almacenada en la propiedad "_subscribe" y le pasa el objeto "observer"
    return this._subscribe(observer);
  }
  // Define un método estático "fromEvent" que acepta dos argumentos: "domElement" y "eventName"
  static fromEvent(domElement, eventName) {
    // Retorna una nueva instancia de la clase "Observable"
    return new Observable(function subscribe(observer) {
      // Define una función "handler" que acepta un argumento "ev"
      const handler = (ev) => {
        // Llama al método "next" del objeto "observer" y le pasa el argumento "ev"
        observer.next(ev);
      };
      // Añade un event listener al elemento DOM "domElement" que escucha el evento especificado en "eventName" y llama a la función "handler" cuando el evento ocurre
      domElement.addEventListener(eventName, handler);
      // Retorna un objeto que contiene un método "unsubscribe"
      return {
        // Define el método "unsubscribe"
        unsubscribe() {
          // Elimina el event listener del elemento DOM "domElement" asociado con el evento "eventName" y la función "handler"
          domElement.removeEventListener(eventName, handler);
        },
      };
    });
  }
}

Creando Observables que devuelven información del evento de la siguiente manera:

const button = document.getElementById("button");
const clicks = Observable.fromEvent(button, "click");
const clicksSubscription = clicks.subscribe({
  next(e) {
    console.log("Click in the button", e); // “e” contiene toda la información del evento
  }
});

clicksSubscription.unsubscribe(); // De esta manera te puedes des-suscribir

Ahora, imaginemos que queremos hacer más operaciones sobre la cadena de datos, como obtener sólo algunos datos del evento o escuchar solo los clicks que se hagan en la parte izquierda del botón 🎯. Vamos a implementar la función map sobre observables.

La función map es una función pura que itera sobre cada elemento de un array y "mapea" cada ítem de un array en otro:

[1, 2, 3].map(elemento => elemento * 2); // Retorna [2, 4, 6]

Para implementar map en observables, haremos lo siguiente:

class Observable {
  ...
  map(projection) {
    const self = this;
    return new Observable(function subscribe(observer) {
      const subscription = self.subscribe({
        next(v) {
          let value;
          try {
            value = projection(v);
            observer.next(value);
          }
          catch(e) {
            observer.error(e);
            subscription.unsubscribe();
          }
        },
        error (e) {
          observer.error(e);
        },
        complete () {
          observer.complete();
        }
      });
      return subscription;
    });
  }
  ...
}

Y ahora, podemos usar map para transformar los datos dentro de nuestro observable, obteniendo solamente la posición del mouse en el momento que hizo click sobre el botón 🖱️.

const button = document.getElementById("button");
const clicks = Observable.fromEvent(button, "click");
const clicksSubscription = clicks
  .map((ev) => ev.offsetX)
  .subscribe({
    next(offSetX) {
      console.log(offSetX);
    },
  });

Echa un vistazo al siguiente Codepen para revisar la definición completa: Codepen

💡 Conclusiones:

  1. Hemos implementado la función map en observables, lo que nos permite realizar transformaciones en los datos de eventos de una manera más flexible.
  2. map en observables es similar a su uso en arrays, permitiendo aplicar una función de proyección a cada elemento.
  3. Al usar map en observables, podemos realizar operaciones más avanzadas y personalizadas en la cadena de datos, lo que mejora la calidad y eficiencia de nuestro código.

🏋️‍♂️ Ejercicios para practicar:

  1. Implementa la función filter en observables para permitir filtrar eventos basados en una condición específica.
  2. Crea un observable que devuelva eventos de teclado y usa map para transformar la salida en objetos que contengan solo la tecla presionada y el tiempo en el que ocurrió el evento.
  3. Combina el uso de map y filter en observables para procesar eventos de mouse y devolver solo la información relevante de aquellos eventos que cumplan ciertos criterios.

🔖 Resumen de 3 puntos:

  1. Hemos ampliado nuestra implementación de Observables con el operador map, lo que nos permite transformar los datos de los eventos de forma más flexible y eficiente.
  2. La función map en observables es similar a su uso en arrays, aplicando una función de proyección a cada elemento de la secuencia.
  3. Con map, podemos realizar transformaciones avanzadas y personalizadas en la cadena de datos, lo que nos permite manejar eventos de manera más efectiva en nuestras aplicaciones.

¡Excelente! Espero que este post te haya sido útil y te haya ayudado a comprender cómo implementar el operador map en Observables. Si tienes alguna pregunta o comentario, no dudes en dejarlo en la sección de comentarios. ¡Buena suerte en tus proyectos y no olvides seguir aprendiendo y practicando! 🚀

Si te gustó este post, no olvides compartirlo con tus amigos y colegas a través de las redes sociales utilizando los enlaces proporcionados. ¡Hasta la próxima!

Sebastian Gomez

Sebastian Gomez

Creador de contenido principalmente acerca de tecnología.

Leave a Reply

0 Comments

Related Posts

Categorias