No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Evitando el callback hell

15/23
Recursos

Uno de los principales problemas de los observables es el Callback Hell. La anidación de N cantidad de suscripciones, una dentro de la otra, vuelve tu código muy difícil de mantener y de leer.

Cómo solucionar el Infierno de Callbacks

Utilizando promesas, puedes resolver este problema fácilmente con async/await. Pero si hablamos de observables, nuestra mejor amiga, la librería RxJS, llega para aportar su solución.

Un ejemplo común de esta problemática en Angular es como la siguiente.

readAndUpdate(): void {
  // Ejemplo de callback hell
  this.apiService.getProduct(1)
    .subscribe(res => {
      this.apiService.updateProduct(1, { name: 'Nuevo nombre del producto' })
        .subscribe(res2 => {
          // ...
        });
    });
}

Donde se está realizando una petición para la lectura de un producto e inmediatamente se está actualizando el mismo. Generando un subscribe dentro de otro.

¿Cómo resolver este problema de Callback Hell?

Tal vez hasta dos subscribe es aceptable, pero no se recomienda continuar con esa estructura de código y es posible resolverlo de la siguiente manera.

import { switchMap } from 'rxjs/operators';
readAndUpdate(): void {
  // Solución callback hell
  this.apiService.getProduct(1)
    .pipe(
      switchMap(products => this.apiService.updateProduct(1, { name: 'Nuevo nombre' }) )
    )
    .subscribe(res => {
      // Producto actualizado
    });
}

Importando switchMap desde rxjs/operators, lo que hace esta función es recibir el dato que emite un observable, y utilizarlo como input para el segundo. De esta manera, el código queda más limpio y profesional.

Conoce más sobre RxJS

Otra alternativa que brinda RxJS es la posibilidad de manipular varios observables al mismo tiempo. Con las promesas, puedes hacer uso de Promise.all([]) para realizar N procesamientos asincrónicos en paralelo y obtener sus resultados.
De forma muy similar, en RxJS puedes hacer lo siguiente.

import { zip } from 'rxjs';
readAndUpdate(): void {
  // Agrupando observables en un mismo subscribe
  zip(
    this.apiService.getProduct(1),
    this.apiService.updateProductPATCH(1, { name: 'Nuevo nombre' })
  )
  .subscribe(res => {
    const get = res[0];
    const update = res[1];
  });
}

Importando la función zip, puedes crear un array de observables y suscribirte a todos ellos al mismo tiempo. Diferenciando por el índice de cada uno el resultado de la operación que ejecutaron para obtenerlo.

En este ejemplo, el índice 0 posee el resultado de la lectura y el índice 1 el del update.


Contribución creada por: Kevin Fiorentino.

Aportes 13

Preguntas 1

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Sería un buen complemento en la escuela de Angular, un curso de Rxjs.

Un curso de Rxjs, plis. 0_o

Muy buena la clase y la explicación del profesor, pero quiero aportar de que hay otros métodos que nos ayudan a realizar peticiones en paralelo en los observables, solo que hay que tener claro su uso y estos son: forkJoin, combineLatest y withLatestFrom.
Para que puedan observar las diferencias dejo por acá este link (https://www.digitalocean.com/community/tutorials/rxjs-operators-forkjoin-zip-combinelatest-withlatestfrom) donde se evidencian las diferencias de cada uno de ellos.

Para obtener los elementos del array (para el caso de Zip) cuando se conoce la posición y el tipo de dato, es más sencillo hacerlo así

const [read, update] = response;

Dejo los codigos de los servicios que hice

  fetchReadAndUpdate(id: string, dto:UpdateProductDTO) {
    return zip(
      this.getProduct(id),
      this.update(id, dto)
    );
  }

  getProductAndupdate(id: string, dto:UpdateProductDTO){
    return this.getProduct(id)
      .pipe(
        switchMap((product) => this.update(product.id, dto))
      )
  }

Y tambien como los llamo del lado del componente:

  readAndUpdate(id: string){
    this.productsService.getProductAndupdate(id, {title: 'change'})
      .subscribe(data => {
        console.log(data);
      });

    this.productsService.fetchReadAndUpdate(id, {title: 'change'})
    .subscribe(response => {
      const product = response[0];
      const update = response[1];
    })

  }

Wow que clase!!
En verdad las cosas que aprendi en esta clase me ayudaran mucho en mi crecimiento profecional

Rxjs es mi pastor

Siii, Yo también creo que es muy importante un curso de programación reactiva con RxJS.

excelente clase,Nico como siempre.

Cada que avanzo en el curso me doy cuenta de lo increible y asombroso que es el Framework, tantas formas de solucionar problemas y todo tan claro con Nico, no me la creo jaja.

Zip , similar a PromiseAll()

https://rxjs.dev/
Documentacion de Rxjs!