在Node.js中限制asynchronous调用

我有一个Node.js应用程序获取本地文件列表,并将其上传到服务器。 该列表可能包含数千个文件。

for (var i = 0; i < files.length; i++) { upload_file(files[i]); } 

如果我用数千个文件执行这个操作,upload_file将一次被调用几千次,而且很可能会死亡(或者至less是挣扎)。 在同步世界中,我们将创build一个线程池并将其限制到一定数量的线程。 有没有简单的方法来限制一次执行多less个asynchronous调用?

像往常一样,我推荐Caolan McMahon的asynchronous模块 。

让你的upload_file函数进行callback,因为它是第二个参数:

 var async = require("async"); function upload_file(file, callback) { // Do funky stuff with file callback(); } var queue = async.queue(upload_file, 10); // Run ten simultaneous uploads queue.drain = function() { console.log("All files are uploaded"); }; // Queue your files for upload queue.push(files); queue.concurrency = 20; // Increase to twenty simultaneous uploads 

上面的答案是:在NPM上的asynchronous是最好的答案,但是如果你想了解更多关于控制stream的信息,


您应该考虑控制stream模式。 在Mixu的Node Book第7章中有关于控制stream模式的精彩讨论。 也就是说,我将看7.2.3中的例子: 有限并行 – 一个asynchronous,并行,并发限制for循环

我已经调整了他的例子:

 function doUpload() { // perform file read & upload here... } var files = [...]; var limit = 10; // concurrent read / upload limit var running = 0; // number of running async file operations function uploader() { while(running < limit && files.length > 0) { var file = files.shift(); doUpload(file, function() { running--; if(files.length > 0) uploader(); }); running++; } } uploader(); 

你应该尝试排队。 我假设upload_file()完成时触发一个callback。 这样的事情应该做的(未经testing):

 function upload_files(files, maxSimultaneousUploads, callback) { var runningUploads = 0, startedUploads = 0, finishedUploads = 0; function next() { runningUploads--; finishedUploads++; if (finishedUploads == files.length) { callback(); } else { // Make sure that we are running at the maximum capacity. queue(); } } function queue() { // Run as many uploads as possible while not exceeding the given limit. while (startedUploads < files.length && runningUploads < maxSimultaneousUploads) { runningUploads++; upload_file(files[startedUploads++], next); } } // Start the upload! queue(); } 

其他答案似乎已经过时了。 这可以很容易地解决从asynchronous使用paralleLimit 。 以下是如何使用它。 我没有testing过。

 var tasks = files.map(function(f) { return function(callback) { upload_file(f, callback) } }); parallelLimit(tasks, 10, function(){ });