javascript - 在 Node.js 中难以停止子进程生成中的流?

标签 javascript node.js promise bluebird child-process

我正在尝试使用 Node.js 子进程生成。下面的代码将执行某些 shell 命令并读取数据作为生成进程提供的缓冲流监听器。 Bluebird Node 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
    })

我的问题是,如果在任何人 promise 的执行过程中出现任何错误,它应该到达“cmdExec.stderr.on”并拒绝 promise 。即使在将控制台日志放入“cmdExec.stdout.on”流中时出现错误,我也无法停止接收缓冲流。

我想知道如果子进程遇到任何错误,是否有任何特定的方法可以停止子进程的执行,并通过抛出错误来停止,而不是继续接收流。

预先感谢您的任何建议或想法。

最佳答案

感谢您的意见和建议。我找到了解决停止绑定(bind)到子进程生成的事件监听器问题的方法。在上面的代码中,每当调用promise.all时,都会依次触发多个处理程序,并创建生成进程和各种监听器。如果promise下的任何一个spawn进程发生错误,则需要抛出一个错误并立即停止所有创建的spawn进程。

我的解决方案是将创建过程中的所有生成过程存储在一个数组中。当任何一个生成进程遇到错误时,都会调用中断“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()
    })     
}

我想验证我的方法,并让我知道是否有更好的方法可以解决这种情况。提前致谢。

关于javascript - 在 Node.js 中难以停止子进程生成中的流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52747777/

相关文章:

javascript - ES6 Promises 在 catch 之前返回

javascript - 这个 JavaScript 如何在 Firefox 中打开 Windows 设置?

node.js - 在 docker 中运行 npm update,而不使用该特定更新的缓存

node.js - 即使字段从文档中删除,Mongoose 也会返回字段的默认值

javascript - JS Q 库 - 延迟错误捕获

node.js - NodeJS eventloop 执行顺序(process.nextTick and promise)

javascript - 视频元素上的 captureMediaStream() mediaStreamTrack 结束事件不会触发?

javascript - 等待单个 promise 与异步迭代器的异步解析顺序

javascript - Fullcalendar js 事件重叠

linux - 在 linux 上,如何将文本环绕命令的输出并将其保存到文件中?