Я пытаюсь использовать Node.js Child process spawn. Ниже код выполнит определенные команды оболочки и прочитает данные как прослушиватели потоков буфера, предоставленные процессом spawn. Модуль обездвиживания узла Bluebird используется для обертывания дочернего процесса.
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", я не мог прекратить прием потоков буфера.
Я хотел бы знать, есть ли какой-либо конкретный способ остановить выполнение дочернего процесса, если он сталкивается с какой-либо ошибкой и останавливается, бросая ошибку вместо того, чтобы продолжать получать потоки.
Заранее благодарим за любые предложения или идеи.
Спасибо за комментарии и предложения. Я выяснил, как решить проблему остановки Eventlistener, привязанного к дочернему процессу. В приведенном выше коде всякий раз, когда появляется обещание. All, вызывается и, в свою очередь, запускается многократным обработчиком с процессом порождения, созданным вместе с различными слушателями. Если одна ошибка произошла в любом из процессов икры в соответствии с обещанием, необходимо будет выбросить ошибку и немедленно остановить весь созданный процесс появления.
Мое решение - хранить весь процесс появления при создании массива. При столкновении с каким-либо одним процессом всплытия вызовет прерывание "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()
})
}
Я хотел бы подтвердить свой подход и сообщить, что для решения этой проблемы доступен более эффективный подход. Заранее спасибо.
cb
. Удалите его и все его использования, и вместо этого просто вызовитеcp.then(parsingMethodHandler)
. Кроме того,return
внутреннее обещание из обратного вызоваthen
чтобы вам не требовались отдельные.catch()
- внешнего должно хватить.promises
? В вашем коде в него вставляется только одно обещание. Это ваш настоящий код?