¿Una llamada a Node.js ‘async.parallel () es sincrónica?

Estoy echando un vistazo al módulo async Node.js para resolver un problema. He implementado una pequeña prueba:

 var async = require("async"); function print(val) { console.log(val); } async.parallel([ function(cb){ print(1); cb(null); }, function(cb){ print(2); cb(null); }, function(cb){ print(3); cb(null); }, function(cb){ print(4); cb(null); }, function(cb){ print(5); cb(null); } ], function(err) { if ( err ) { console.error(err); return; } console.log("Done!"); } ); console.log("Trulu"); 

¿Puedo estar seguro de que la llamada de registro de Trulu nunca se llamará antes de que async.parallel la llamada a async.parallel ? En otras palabras, ¿se llama con seguridad a todas las funciones y la callback final antes de llamar al registro de Trulu?

¿Puedo estar seguro de que la llamada de registro de Trulu nunca se llamará antes de que finalice la llamada a async.parallel?

La llamada en sí, sí.

En otras palabras, son todas las funciones.

Supongo que sí, aunque los documentos no lo mencionan. Sin embargo, no esperaría ningún cambio, ya que es probable que rompa el código existente.

y la última callback llamada antes de que se llame el registro de Trulu seguro?

No. No conoces las funciones, y cuando son asíncronas, la callback final se ejecutará después de Trulu . Si todas las funciones son síncronas, no debería usar async todos modos. De hecho, mientras async.js usa setImmediate internamente, así que algunas devoluciones de llamada (desafortunadamente difíciles de identificar) serán “asincronizadas”, sin embargo, el mantenedor declaró :

Sí, hacer funciones asíncronas se deja al desarrollador

Si desea asegurarse de que las devoluciones de llamada siempre se llamen de forma asíncrona (después de Trulu ), incluso cuando las funciones son síncronas, podría considerar el uso de Promesas compatibles con A + .

Respuesta corta: No son asíncronos.

Respuesta larga:

Tan pronto como haga algo asincrónico, dentro de las devoluciones de llamada de parralel, puede esperar que Trulu sea ​​llamado inmediatamente después. Cuando llamas a cb , anuncia que la función regresó. Cuando todas las funciones hayan regresado, llamará a la última callback.

Por esa razón, si realiza un setTimeout sin tiempo y cada función regresa sin nada asíncrono, podrían comportarse como síncronas porque Javascript solo ejecuta una unidad a la vez. Y como es probable que se inicien en orden, parecerá que se ejecuta de forma síncrona.

Toma esto como un ejemplo:

 var looping = true; setTimeout(function () {looping = false;}, 1000); while(looping) { ... } 

Este código nunca saldrá ya que setTimeout nunca se activará. En async.parralel , estoy casi seguro de que cada callback se ejecutará una vez que la unidad actual haya terminado de ejecutarse. Lo que significa que siempre tendrás tu console.log("Trulu") ejecutado antes de cualquiera de las devoluciones de llamada dentro de async.parralel .

Nota

Si está buscando hacer cosas sincrónicas, no debe usar un módulo llamado async. Es bastante obvio que va a ser asíncrono .

Dicho esto, siento que hay un gran malentendido con el término async . Asíncrono no es un sinónimo de parralelismo o tener cosas simultáneamente. Asíncrona, solo significa “sin orden en el tiempo”. Podría ser simultáneo pero también podría ser secuencial. Para ejecutar código asíncrono en Javascript, debe confiar en un bucle de eventos.

El bucle de eventos solo puede procesar un evento a la vez, setTimeout simplemente pone el evento en el bucle. Tan pronto como un controlador de eventos se va, llega al siguiente evento y así sucesivamente.

En su caso, ya que no está llamando a cb dentro de un controlador de eventos, se los llamará de forma síncrona ya que nunca abandonarán el event actual.

Como ya está usando async, async tiene una llamada en series . Creo que esto puede ser lo que estás buscando, pero una advertencia, esto es feo (porque, en mi opinión, async.js es un desastre).

 async.series([ parallel, function(callBack){ console.log("Trulu"); callBack(null); } ]); function parallel(callBack){ async.parallel([ function(cb){ print(1); cb(null); }, function(cb){ print(2); cb(null); }, function(cb){ print(3); cb(null); }, function(cb){ print(4); cb(null); }, function(cb){ print(5); cb(null); } ], function(err) { if ( err ) { console.error(err); return; } console.log("Done!"); callBack(null); } ); } 

Honestamente, creo que el módulo asíncrono en general está haciendo el javascript mucho más complicado de lo que es de forma nativa. Si desea una respuesta que muestre cómo hacer lo que quiere hacer sin utilizar el módulo async, ¡hágamelo saber!

Otra solución más sencilla sería crear la última llamada que desea ejecutar después de la callback de su async.parallel :

 async.parallel([ function(cb){ print(1); cb(null); }, function(cb){ print(2); cb(null); }, function(cb){ print(3); cb(null); }, function(cb){ print(4); cb(null); }, function(cb){ print(5); cb(null); } ], function(err) { if ( err ) { console.error(err); return; } console.log("Done!"); console.log("Trulu"); // Executes after all your "parallel calls" are done } );