我正在尝试使用Node.js子进程生成。下面的代码将执行某些shell命令,并将数据作为spawn进程提供的缓冲流侦听器读取。蓝鸟节点Promise模块用于包装子进程。
var execSpawn = require('child_process').spawn;
var Promise = require('bluebird');
spawnAction = function(path, cmd, cb){
return function(resolve, reject){
cmdExec = execSpawn(path, cmd);
var fileData = {}
var count = 0;
cmdExec.stdout.on('data', function(data){
if(cb){
fileData = data.toString('utf8');
}else{
if(data =='.'){
count +=1;
}else{
console.log(data.toString('utf8'));
}
}
});
cmdExec.stderr.on('data', function(data){
if(reject){
reject("error in scrubbing "+cmd.slice(-1) + " "+data.toString('utf8'));
}
});
cmdExec.on('exit', function(){
console.log("reach the exit event");
})
cmdExec.on('close', function(){
if(cb){
resolve(cb(fileData));
}else{
resolve(count);
}
});
}
}
使用以下方法多次调用上述方法进行并行执行:
promises = []
cp = new Promise(spawnAction(Path, ['cmd'],parsingMethodHandler));
cp.then(function(data){
data.forEach(function(disk){
var handler = new Promise(self.spawnAction(Path, "next command"));
promises.push(handler);
}
}.then(function(){
Promise.all(promises).then(function(result){
//certain actions
}.catch(function(err){
//catch error specific to the failure of promise handler
})
}).catch(function(err){
//error specific to the first promise
})
我的问题是,如果在执行任何人的承诺期间出现任何错误,它应该到达“ cmdExec.stderr.on”并拒绝该承诺。即使错误使控制台日志放入“ cmdExec.stdout.on”流中之后,我也无法停止接收缓冲区流。
我想知道是否有任何特定的方法可以停止子进程的执行,如果它遇到任何错误并通过抛出错误而不是继续接收流而停止。
预先感谢您的任何建议或想法。
答案 0 :(得分:0)
感谢您的评论和建议。我想出了一种方法来解决停止将Eventlistener绑定到子进程生成的问题。在上面的代码中,每当调用promise.all时,依次触发带有多个侦听器创建的生成进程的多个处理程序。如果在promise的任何一个生成过程中发生任何错误,都将需要抛出一个错误并立即停止所有创建的生成过程。
我的解决方案是将创建过程中的所有生成过程存储在一个数组中。在任何一个生成过程中遇到错误时,都会调用中断“ SIGINT”以立即终止所有操作。这将立即停止进程执行并抛出错误。您可以在下面找到代码段
var execSpawn = require('child_process').spawn;
var Promise = require('bluebird');
var child_process_list = []
var spawnAction = function(path, cmd, cb){
return function(resolve, reject, onCancel){
cmdExec = execSpawn(path, cmd);
child_process_list.push(cmdExec);
var fileData = {}
var count = 0;
cmdExec.stdout.setEncoding('utf8');
cmdExec.stdout.on('data', function(data){
//Certain actions with filedata and count;
console.log(data);
});
cmdExec.stderr.on('data', function(data){
while(child_process_list.length > 0){
proc = child_process_list.pop();
proc.kill('SIGINT');
}
if(reject){
reject("error "+cmd.slice(-1) + " "+data.toString('utf8'));
}
});
cmdExec.on('close', function(){
if(cb){
resolve(cb(fileData));
}else{
resolve(count);
}
});
}
}
var handle = function(path, cmd, cb) {
var promises = []
cp = new Promise(spawnAction(path, ['cmd'],parsingMethodHandler));
cp.then(function(data){
data.forEach(function(disk){
cmd.push(disk);
var handler = new Promise(self.spawnAction(path, cmd));
promises.push(handler);
});
}).then(function(){
Promise.all(promises).then(function(result){
console.log("result => ",result);
child_process_list = [];
cb();
}).catch(function(err){
console.log("error call => ",err);
cb();
})
}).catch(function(err){
console.log("Failed in fetching drive path available ",err);
cb()
})
}
我想验证我的方法,并让我知道可以使用任何更好的方法来解决这种情况。预先感谢。