JavaScript asíncrono para cada uno

Shraddha Paghdar 20 junio 2023
JavaScript asíncrono para cada uno

En la publicación de hoy, veremos si podemos usar async en el bucle forEach de JavaScript. ¿Cuáles son las alternativas?

Asíncrono forEach en JavaScript

La programación asíncrona no está pensada para Array.prototype.forEach. Es inapropiado para async-await, tal como lo fue para las promesas.

const employees = await this.getEmployees();

// BAD
await employees.forEach(async (employee) => {
  await giveBonusToEmployee(employee);
});

await sendEmail('All bonuses sent');

Estos son algunos de los problemas con esto:

  1. Las promesas devueltas de la función iteradora no se manejan; por lo tanto, no se notará si uno de ellos comete un error. Si no hay un oyente unhandledrejection registrado en el nodo 10, ¡el proceso fallará!
  2. Todos los bonos se distribuyen simultáneamente en lugar de secuencialmente porque forEach no espera que cada promesa se cumpla una por una. Como resultado, el bucle finaliza antes de que se hayan entregado todas las bonificaciones.
  3. Como resultado, antes de que cualquiera de los bonos se haya entregado por completo, sendEmail() envía el correo electrónico. Tal vez no se entregue ninguno; ¡Todos podrían arrojar errores!

A continuación se muestra la solución que podemos implementar para esto:

  1. Procesar cada bono en serie. Puede utilizar la construcción for...of ya que JavaScript admite async-await.
for (const employee of employees) {
  await giveBonusToEmployee(employee);
}

Antes de pasar al siguiente bono, este bucle esperará a que se entregue el anterior. Aunque sería más detallado de lo que necesitamos, también podrías usar un típico for(...;...;...) en esta situación.

  1. Procesar todos los bonos en paralelo.
await Promise.all(employees.map(async (employee) => {
  await giveBonusToEmployee(employee);
}));

Puede ser más rápido analizar a todos los empleados simultáneamente si el orden no importa. Esto comenzará a dar todas las bonificaciones a la vez, pero no sendEmail() hasta que se hayan enviado todas las bonificaciones.

Los bucles for y while funcionan naturalmente con async-await porque están escritos en el cuerpo de la función original. Sin embargo, cuando llama a otra función, async-await solo se puede usar si la función llamada devuelve una promesa y maneja esa promesa.

Debido a que tanto .reduce() como .map() producen una promesa o una serie de promesas que podemos esperar, podemos usarlas.

Sin embargo, la mayoría de los métodos de matriz no devuelven promesas ni permiten que se pasen promesas de una llamada a otra, lo que hace imposible utilizarlas de forma asíncrona. Como resultado, el código asíncrono no se puede usar dentro de una matriz, por ejemplo, array.some() o array.filter().

Shraddha Paghdar avatar Shraddha Paghdar avatar

Shraddha is a JavaScript nerd that utilises it for everything from experimenting to assisting individuals and businesses with day-to-day operations and business growth. She is a writer, chef, and computer programmer. As a senior MEAN/MERN stack developer and project manager with more than 4 years of experience in this sector, she now handles multiple projects. She has been producing technical writing for at least a year and a half. She enjoys coming up with fresh, innovative ideas.

LinkedIn

Artículo relacionado - JavaScript Async

Artículo relacionado - JavaScript Loop