难于在Node.js的子进程中停止生成流? [英] Facing difficulty to stop the stream in child process spawn in Node.js?

查看:61
本文介绍了难于在Node.js的子进程中停止生成流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Node.js子进程生成.下面的代码将执行某些shell命令,并将数据作为spawn进程提供的缓冲流侦听器读取.蓝鸟节点Promise模块用于包装子进程.

I am trying to use Node.js Child process spawn. Below code will execute the certain shell commands and read the data as buffer streams listener provided by spawn process. Bluebird node promise module is used to wrap around the child process.

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);
        }
    });
}

}

多次使用以下方法多次调用上述方法进行并行执行:

Above method is called multiple times for parallel execution using the following ways:

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"流中之后,我也无法停止接收缓冲区流.

And my problem is if in case any error during the execution of anyone promises it should reach "cmdExec.stderr.on" and do the reject the promise. Even after the error am getting console logs placed inside "cmdExec.stdout.on" streams, I couldn't stop receiving the buffer streams.

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

I would like to know is there any specific way to stop the child process execution if it faces any error and stopped by throwing the error instead of proceeding in receive the streams.

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

Thanks in advance for any suggestions or ideas.

推荐答案

感谢您的评论和建议.我想出了一种方法来解决停止将Eventlistener绑定到子进程生成的问题.在上面的代码中,每当调用promise.all时,依次触发带有生成的生成程序的多个处理程序以及各种侦听器.如果在promise的任何一个生成过程中发生了一个错误,都将需要抛出一个错误并立即停止所有创建的生成过程.

Thanks for the comments and suggestions. I figured out the way to resolve the problem of stop the Eventlistener binded to child process spawn. In the above code, whenever promise.all is called and in turn fired multiple handler with spawn process created along with various listeners. If one error occurred in any one of the spawn process under the promise will need to throw an error and stop all the created spawn process immediately.

我的解决方案是将创建过程中的所有生成过程存储在一个数组中.遇到任何一个生成过程的错误时,都会调用中断"SIGINT"以立即终止所有操作.这将立即停止进程执行并抛出错误.您可以在下面找到代码段

My solution is store all the spawn process during creation in an array. On facing error with any one spawn process will call interrupt "SIGINT" to kill all actions immediately. This stops the process execution immediately and throw the error. You can find code snippet below

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()
    })     
}

我想验证我的方法,并让我知道可以使用任何更好的方法来解决这种情况.预先感谢.

I would like to validate my approach and let me know any better approach is available to address this situation. Thanks in advance.

这篇关于难于在Node.js的子进程中停止生成流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆