Header Ads Widget

Ticker

6/recent/ticker-posts

Promise.all () y map () con Async / Await por ejemplo

 En este ejemplo rápido, aprenderemos cómo usar Promise.all()map()con Async/AwaitJavaScript para impelemtizar ciertos escenarios que no se pueden implementar con bucles for async/await.

Ejemplo de promesas de JavaScript que dependen unas de otras

La mayoría de las veces al realizar operaciones asincrónicas, en aplicaciones del mundo real. como las solicitudes http que devuelven algunos datos de un servidor, deberá realizar otras solicitudes posteriores que dependan entre sí.

Por ejemplo, supongamos que tenemos el siguiente método para obtener un montón de categorías de productos

// La primera promesa devuelve una matriz después de un retraso js const getProducts = () => { return new Promise((resolve, reject) => { return setTimeout( () => resolve([{ id: 'product1' }, { id: 'product2' }, { id: 'product3'}, { id: 'product4'}]), 1000 ) }) }

Usamos el setTimeoutmétodo para resolver la promesa con una variedad de productos después de un segundo para simular una solicitud http real que normalmente demoraría algún tiempo en regresar.

Después de obtener los productos, necesitaremos obtener el ID de cada producto con un código similar a este:

// this promise depends on the result of the previous promise
const getProductId = (category) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(category.id), 1000)
  })
}

También necesitaremos una tercera promesa que depende de la segunda promesa:

const capitalizeId = (id) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 700)
  })
}

Combinar y resolver todas las promesas con For Loop y Async / Await

Ahora, ¿cómo combinar todas estas promesas para obtener los productos y capitalizar sus identificaciones?

Dado que el primero devuelve una matriz, podemos esperar a que se resuelva e iterar sobre la matriz y ejecutar las otras dos promesas posteriormente, es decir, para cada elemento de la matriz, esperamos getProductIda que se resuelva la promesa y luego llamamos a la capitalizeIdpromesa de la siguiente manera:

const capitalizeProductsIds = async () => {
  const products = await getProducts()

  for (let product of products) {
    const productId = await getProductId(product);
    console.log(productId);

    const capitalizedId = await capitalizeId(productId);
    console.log(capitalizedId);
  }

  console.log(products);
}

capitalizeProductsIds()

Combinar la async/awaitsintaxis con el for..ofbucle nos dará el siguiente resultado


product1
PRODUCT1

product2
PRODUCT2

product3
PRODUCT3

product4
PRODUCT4

(4) [{…}, {…}, {…}, {…}]

Ese no es el comportamiento que realmente estamos buscando implementar, sino que queremos ejecutar la primera promesa y esperar a que se complete, luego la segunda promesa y finalmente la tercera promesa cuando la segunda se complete por completo.

La combinación y la resolución de todas las promesas con Promise.all()map()yAsync/Await

Entonces, en lugar de usar el bucle for con la async/awaitsintaxis, necesitamos usar los métodos Promise.all()map()con async/awaitlo siguiente:

const capitalizeProductsIds = async () => {
  const products = await getProducts()

  Promise.all(
    products.map(async (product) => {
      const productId = await getProductId(product);
      console.log(productId);

      const capitalizedId = await capitalizeId(productId)
      console.log(capitalizedId);
    })
  )

  console.log(products);
}
capitalizeProductsIds();

Esta es la salida:

(4) [{…}, {…}, {…}, {…}]

product1
product2
product3
product4

PRODUCT1
PRODUCT2
PRODUCT3
PRODUCT4

Entonces, la primera promesa se resolverá, luego todas las promesas devueltas getProductId()para cada producto y finalmente todas las promesas devueltas capitalizeId()para cada ID devuelta de las promesas anteriores.

Según MDN :

El método Promise.all () toma un iterable de promesas como entrada y devuelve una sola Promesa que se resuelve en una matriz de los resultados de las promesas de entrada. Esta promesa devuelta se resolverá cuando todas las promesas de entrada se hayan resuelto o si la entrada iterable no contiene promesas. Rechaza inmediatamente después de que se rechacen las promesas de entrada o las no promesas arrojan un error, y las rechazará con este primer mensaje / error de rechazo.


Publicar un comentario

0 Comentarios