是调用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 } );
- 如何在node.js中asynchronous执行多个REST API请求?
- 使用async.js进行asynchronous树遍历
- 将parameter passing给async.js任务
- Async.js – ETIMEDOUT和callback已经被调用
- 节点asynchronous – 工作asynchronous方法在async.parallel内返回undefined
- node.jsasynchronous串行函数的参数
- 为什么瀑布和series / parallelLimit(1)之间的async.js不一致?
- NodeJSasynchronous – 即使有一些失败,仍继续执行多个http请求
- async.each在完成所有迭代后callback