【问题标题】:How to run and handle errors in child process spawn in node如何在节点中生成子进程时运行和处理错误
【发布时间】:2017-05-20 04:21:54
【问题描述】:

我正在使用节点child_process 在系统中生成进程。我可以使用在dataerrorendexit 事件上触发的回调来控制来自stdinstderr 等的data 输出。

问题是当我像这里加载可执行文件时:

/**
 * Load model in memory
 */
Executable.prototype.load = function() {
    var self=this;
    this.onExitCallback=null;
    this.onDataCallback=null;
    this.onErrorCallback=null;
    return new Promise(function(resolve, reject) {
        self.emitDeferred(EVENT_LOAD_START);
        if( self.child ) {
            self.emitDeferred(EVENT_LOAD_DONE);
            return resolve(true);
        }
        self.onErrorCallback = function(error) {
            return reject(error);
        }
        var args =[
            '-input',
            '-'
        ];
        if( self._options.debug) console.log("load",args);
        self.child=self.exec('runner', self._options.bin, args, self._options.child);
        if(self._options.debug) self.child.stdout.pipe(process.stdout);
        self.emitDeferred(EVENT_LOAD_DONE);
        return resolve(true);
    });
}//load

我在error 回调中收到错误,我将调用resolvereject,因为后者将被onErrorCallback 触发,而第一个将在调用之后立即触发spawn,而我需要避免resolve,同时保持onErrorCallback

这是我的exec 代码:

    /**
     * Execute child process
     */
    this.exec = function(name,command,params,options) {
        var self=this;
        var _options = { detached: false };
        for (var attrname in options) { _options[attrname] = options[attrname]; }

        var created_time= ( new Date() ).toISOString();
        var task = require('child_process').spawn(command, params, _options);
        task.stdout.on('data', function(_data) {
            if( self.onDataCallback ) self.onDataCallback.apply(self,[ new Buffer(_data,'utf-8').toString() ] );
        });
        task.on('error', function(error) {
            if(self._options.debug) console.error("exec:%s pid:%d error:\n",name,task.pid,error);
            if( self.onErrorCallback ) self.onErrorCallback.apply(self,[error]);
        });
        task.on('uncaughtException', function (error) {
            if(self._options.debug) console.error("exec:%s pid:%s uncaughtException:\n",name,task.pid,error);
            if( self.onErrorCallback ) self.onErrorCallback.apply(self,[error]);
        });
        task.stdout.on('end', function(data) {
            if(self._options.debug) console.log("exec:%s end.",name);
        });
        task.stderr.on('data', function(data) {
            //if(self._options.debug) console.log("exec:%s stderr:%s",name,data);
            //if(!data) task.kill('SIGINT');
        });
        task.on('close', (code, signal) => {
            if(self._options.debug) console.warn('task:%s pid:%s terminated due to receipt of signal:%s',name,task.pid,signal);
        });
        task.on('exit', function(code) {
            if(self._options.debug) console.log("exec:%s exit.",name);
            if (code != null && code != 0) {
                var error=new Error();
                error.description= command + ' ' + params.join(' ');
                error.code=code;
                if(self._options.debug) console.error("exec:%s pid:%d error:\n",name,task.pid,error);
                task.kill('SIGINT');
                if( self.onExitCallback ) self.onExitCallback.apply(self,[error]);
            } else {
                // at exit explicitly kill exited task
                task.kill('SIGINT');
                if( self.onExitCallback ) self.onExitCallback.apply(self);
            }
        });
        return task;
    }//exec

send 代码将原始数据发送到正在运行的子进程:

    /**
     * Send data to child process
     */
    this.send = function(data) {
        this.child.stdin.setEncoding('utf-8');
        this.child.stdin.write( data + '\r\n' );
    }//send

所以要测试它就像这样做

myExecutable.load()
.then(done => {
    console.log("loaded %d", done);
})
.catch(error => {
    console.error("error",error);
});

【问题讨论】:

    标签: javascript node.js child-process spawn


    【解决方案1】:

    您可以使用try{}catch(err){} 机制,您可以将 onErrorCallback 触发的代码放入 catch 中,从而在保持 onErrorCallback 完整的同时避免解析。

    【讨论】:

    • 谢谢,如果可能的话,我想根据child_process 事件使用不同的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多