DEV Community

Cover image for Ejecuta código asíncrono de forma concurrente en Javascript
Matías Hernández Arellano
Matías Hernández Arellano

Posted on • Updated on • Originally published at matiashernandez.dev

Ejecuta código asíncrono de forma concurrente en Javascript

Este artículo fue originalmente escrito en https://matiashernandez.dev

Las Promesas en Javascript son la forma standard de ejecutar código asíncrono, y son por naturaleza concurrentes.

> Quieres saber más sobre como trabajar con promesas? Te invito a leer esté artículo: [¿WTF es una promesa en JS?](https://matiashernandez.dev/blog/post/wtf-que-es-una-promesa-en-javascript)

Dado que una Promesa no pausa o detiene la ejecución de tu código, es sencillo llamar múltiples promesas al mismo tiempo.
Enter fullscreen mode Exit fullscreen mode

getData("userId").then(result => {})

getData("anotherUser").then(result =>{})
Enter fullscreen mode Exit fullscreen mode

Estas dos promesas se ejecutarán "al mismo" tiempo, pero, no tienes forma de controlar cuando serán resueltas, además de que, si son varias promesas ejecutadoas, el código se verá algo complejo de leer entre tanto use the then y catch.

Aquí es donde muchos echan mando de async/awaitç

A modo resumen, la sintáxis async/await te permite pausar la ejecución de una promesa hasta que esta sea resuelta, creando un flujo de datos sencillo de entender.

const result1 = await getData("userId")

const result2 = await getData("anotherUser")
Enter fullscreen mode Exit fullscreen mode

Ahora, tienes control sobre cuando cada promesa termina y es resuelta, y puedes utilizar las variables result1 y result2 directamente sin tener que usar un callback como en el caso anterior (dentro de then).

Pero ahora, las promesas ya no se ejecutan en paralelo.

Para saber más sobre async/await te invito a leer este otro artículo
Entendiendo async/await

Entonces, como ejecutar promesas de forma concurrente pero mantener un flujo "sincrono"?

Promise.all

El objecto Promise tiene varios métodos estáticos asociados, uno de ellos es Promise.all.

Este método recibe como argumento un arreglo de promesas y retorna una sola que será resuelta cuando todas las otras lo hayan hecho.

Como resultado, tendrás que lidear solo con una promesa y además, mantendrás la capacidad de ejecutar las promesas de forma concurrente.

const promise1 = getData("userId")

const promise2 = getData("anotherUser")

try {
    const [ result1, result2 ] = await Promise.all([ promise1, promise2])
}catch(error) {
     console.error(error)
        // Este error será el de alguna de las promesas que falló
}
Enter fullscreen mode Exit fullscreen mode

Revisa la documentación de Promise.all en MDN

El único problema que encontrarás al utilizar Promise.all es que si una de las promesas que pasaste como argumento falla, también lo hará Promise.all.

Además, ten encuenta que Promise.all tiene un comportamiento de fallo rápido, es decir, en el momento en que una de las promesas falle, Promise.all fallará y cancelara las promesas restantes.

SI no te gusta utilizar Promise.all por algún motivo en particular, puedes conseguir un resultado muy similar utilizando async/await pero con una pequeña variación a la hora de escribir.

Recuerda, el objetivo es ejecutar las promesas de forma concurrente.

const promise1 = getData("userId")

const promise2 = getData("anotherUser")

try {

        const result1 = await promise1
    const result2 = await promise2

}catch(error) {
     console.error(error)
        // Este error será el de alguna de las promesas que falló
}
Enter fullscreen mode Exit fullscreen mode

Ese código ejecutará ambas promesas antes de pausar por el resultado de cada una. El único problema es que ahora eres tu quien decide que promesa esperar primero.

La ventaja de Promise.all es que el tiempo de ejecución será igual al de la promesa mas lenta (en vez de sumarse como en el caso secuencial), y también que será el navegador quien se encarge de "esperar" cada promesa.

Footer Social Card.jpg
✉️ Únete a Micro-bytes 🐦 Sígueme en Twitter ❤️ Apoya mi trabajo

Top comments (0)