是调用Node.js的async.parallel()同步吗?

我正在看看Node.js的async模块来解决一个问题。 我已经实施了一个小testing:

 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"); 

我可以确定在调用async.parallel之前,Trulu日志调用将永远不会被调用吗? 换句话说,在Trulu日志被调用之前调用的所有函数和最终callback函数都是如此吗?

我可以确定在调用async.parallel之前,Trulu日志调用将永远不会被调用吗?

电话本身,是的。

换句话说,所有的function

我想是这样,虽然文件没有提到它。 不过,我希望不会有任何改变,因为这可能会破坏现有的代码。

并在Trulu日志调用之前调用的最终callback是肯定的?

不,你不知道函数,当它们是asynchronous的时候,最后的callback将在Trulu之后执行。 如果所有的function都是同步的,那么不应该使用async 。 事实上,尽pipeasync.js在内部使用了setImmediate所以一些callback(不幸的是难以识别)将是“不同步的”,但维护者说 :

是的,使functionasynchronous是留给开发者

如果要确保callback总是asynchronous调用(在Trulu之后),即使函数是同步的,也可以考虑使用符合A +的Promise 。

简短的回答:不,他们是asynchronous的。

很长的回答:

只要你做了asynchronous的事情,在parralelcallback中,你可以期待Trulu立即被调用。 当你调用cb ,它宣布函数返回。 当所有的函数都返回时,它会调用最后一个callback函数。

所以出于这个原因,如果你没有时间执行setTimeout ,并且每个函数都返回没有任何asynchronous,他们可能会像同步一样,因为JavaScript一次只运行一个单元。 而且,由于它们可能是按顺序启动的,它看起来好像是同步运行。

以此为例:

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

这段代码永远不会离开,因为setTimeout永远不会被触发。 在async.parralel ,我几乎可以确定每个callback将在当前单元运行完成后执行。 这意味着,您将始终在console.log("Trulu")任何callback之前执行console.log("Trulu")

注意

如果你正在寻找同步的东西,你不应该使用一个叫async的模块。 这是非常明显的,它将是asynchronous的

这就是说,我觉得对于async这个词有一个很大的误解。 asynchronous并不是同步或同时发生事物的同义词。 Asynchrone,只是意味着“没有时间顺序”。 它可能是同时的,但也可能是顺序的。 要在Javascript上运行asynchronous代码,您必须依赖事件循环。

事件循环一次只能处理一个事件, setTimeout只是把事件放在循环中。 只要事件处理程序离开,它就会进入下一个事件,依此类推。

在你的情况下,因为你不是在一个事件处理程序中调用cb ,他们将被同步调用,因为他们从不离开当前event

由于您已经使用asynchronous,asynchronous有一个series调用。 我认为这可能是你正在寻找的,但一个警告,这是丑陋的(因为在我看来,async.js天生就是一团糟):

 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); } ); } 

老实说,我认为一般的asynchronous模块正在使JavaScript比本地更复杂。 如果你想要一个答案,显示如何做你想做的事情,而不使用asynchronous模块,请让我知道!

另一个更简单的解决scheme是在async.parallel的callback中构build你想要执行的最后一个调用:

 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 } );