asynchronous在nodejs的foreach

在node.js中,我知道array.forEach是阻塞的。

我需要通过一个数组循环,并build立一个像这样的string:

var rarray = ['test', 'test2']; var rstring = ''; rarray.forEach(function(e, i){ rstring = rstring + i + e; }); return rstring; 

我怎么做asynchronous?

在这种情况下,您可能不需要将此代码转换为其asynchronous版本。

假设,或者对于非常大的数组,heres是一种将代码转换为asynchronous的方式,或者至less是定期返回到主事件循环的方式。

 var rarray = ['test', 'test2']; var rstring = ''; var max = rarray.length; var current = 0; process.nextTick(function next() { rstring = rstring + rarray[current++]; if (current >= max) { console.log("done", rstring); } else { process.nextTick(next); } }); 

实际上,你可以把它封装在一个函数中,通过调用完成callback来replaceconsole.log

我可能会补充说,你正在尝试做的事实上叫做reduce 。 你可以这样写( doc )

 var res = array.reduce(function(prev, current, index) { return prev + index + current ; }, ''); 

这样做可以做到asynchronous

 var array = ['one', 'two']; function reduceAsync(collection, initial, process, callback) { var i = 0; var res = initial; function DO(err, result) { if(err) return callback(err); if(i > collection.length) return callback(null, res); var index = i++; var value = collection[index]; process(res, value, index, collection, DO); } DO(null, res); } reduceAsync(array, '', function(previous, current, index, collection, callback) { setTimeout(function() { callback(null, previous + index + current); }, 10); // wait 10 ms }, function finalResult(err, result) { console.log(result); }) 

或者,你知道,你可以使用async.reduce

帕斯卡的答案本质上是一种合作multithreading的forms(见维基百科:线程 )。

如果没有测量就很难说,但是我猜想抢先式multithreading对于这种事情会有更好的吞吐量,因为编译器有机会做循环优化(不确定这会发生在上面的代码中),而且操作系统可能更好地决定任务切换的频率。 看起来您可以在node.js中执行Web Worker线程 。

任何人都有基准?

如果你想用上面的代码使用asynchronous模块,你仍然会得到同步代码。 asynchronous模块允许您避免callback地狱和pipe理您的callback。 它不会使同步asynchronous。 为了达到这个目的,你需要像在Pascal的答案中一样使用process.nextTick。

如果您正在为数组中的每个项目执行一些额外的asynchronous处理,并且希望在保持顺序的同时汇总每个操作的结果,则可以使用async.eachSeries,如下所示:

 var async = require('async'); var rarray = ['test', 'test2']; var rstring = '', i = 0; async.eachSeries(rarray, function(item, callback){ rstring += (i++) + item; callback(); }, function(err){ console.log(rstring); } ); 

如果你不关心事物的顺序,那么你可以使用async.each,它将并行地执行你的asynchronous处理函数。