Seb*_*ien 5 javascript loops asynchronous exec
假设您要在短代码中为列表中的每个文件夹启动(随机)进程:
var exec = require('child_process').exec;
var folders = [...]; // a list from somewhere
_.each(folders, function(folder) {
exec("tar cvf " + folder + ".tgz " + folder);
});
Run Code Online (Sandbox Code Playgroud)
如果列表很长,我可能最终会同时运行大量进程,这是应该避免的.以受控速率运行执行的相当简单的方法是什么(这里最多5个并发进程)?
编辑:该问题适用于各种异步流(您要在其中控制速率),而不仅仅是针对exec-over-folders问题.
使用async包及其功能:eachLimit
它的作用相同,lodash但是使用异步流处理并使迭代不会一次超出限制:
var async = require('async');
var exec = require('child_process').exec;
var folders = [...]; // a list from somewhere
var maxProcesses = 5; // 5 items at a time
async.eachLimit(
folders, // collection
maxProcesses, // limit
function(folder, next) { // iterator function. args: item, callback
var cmd = "tar -cf " + folder + ".tgz " + folder;
console.log('calling:', cmd);
exec(cmd, function(err, stdOut, stdErr) { // executing cmd
if(err) console.error(err); // if error putting to console
next(); // passing the async flow to handle the next iteration
});
},
function() { // after all iterations finished
console.log('finished processing commands');
});
Run Code Online (Sandbox Code Playgroud)
或者使用parallelLimit:
var async = require('async');
var _ = require('lodash');
var exec = require('child_process').exec;
var folders = [...]; // a list from somewhere
var callStack = [];
_.each(folders, function(folder) { // generating our stack of commands
callStack.push(function(done) {
var cmd = "tar -cf " + folder + ".tgz " + folder;
exec(cmd, function(err, stdOut, stdErr) {
if(err) console.error(err);
done(null, folder);
});
});
});
var maxProcesses = 5; // 5 items at a time
async.parallelLimit(callStack, maxProcesses, function() {console.log('finished');});
Run Code Online (Sandbox Code Playgroud)
"让它看起来更短":)
const
async = require('async'),
exec = require('child_process').exec;
let folders = [...];
async.eachLimit(folders, 5,
(folder, next) =>
exec("tar -cf " + folder + ".tgz " + folder, () => next()),
() => console.log('finished'));
Run Code Online (Sandbox Code Playgroud)
和
const
async = require('async'),
exec = require('child_process').exec;
let folders = [...];
let commands = folders.map(folder => done => exec("tar -cf " + folder + ".tgz " + folder, () => done());
async.parallelLimit(commands, 5, () => console.log('finished'));
Run Code Online (Sandbox Code Playgroud)
如果这个例子中的任何一个对你不好,或者你的系统非常大,那么让我们尝试使用像rsmq这样的消息队列系统