通过spawn从python返回JSON

我有一个Python脚本,需要两个参数; 一个目录和一个文件名。

python脚本将从提供的目录中的特定文件中创build一个JSON对象,并将其作为第二个参数保存。

但是如果第二个参数等于string“stream”,则JSON数据被输出到STDOUT。

我编写了一个节点脚本,它生成一个subprocess,从terminal调用python脚本,并按预期工作。

"use strict"; const spawn = require("child_process").spawn; const command = "(path to python)"; const loc = "(path to .py script)"; const acct = process.argv[2]; const output = process.argv[3]; let callPy = spawn(command, ["erik.py", acct, output], { cwd: loc, stdio: "pipe" }); callPy.stdout.on("data", (data) => { if (data.toString() === "success") { console.log(acct, "generated"); } else { console.log(data.toString()); } }); 

编辑:

我已经解决了这个问题的未标记:花了多一点时间试图实现这个,我还没有find一个令人满意的解决scheme,允许我同步调用从节点的subprocess,信号的python脚本发出的JSON数据,接收数据,然后将数据发送到浏览器。 我试图在subprocess上使用一个承诺链:

 let child = require("child_process").spawn; // or spawnSync let spawn = () => { let spawned = child(command, args, options,(err, stdout, stderr) => { if (err) { console.log(err) }; }); return spawned }; let listen = (child) => { child.stdout.on("data", (data) => { console.log("PID", child.pid); console.log("data from listen func: ", data); return child }); }; let kill = (child) => { child.kill( "SIGTERM" ); } var p = new Promise((res, e) => { res( spawn() ) e( console.error(e) ) }); p.then(result => { return listen(result); }) p.then(result => { return kill(result); }); 

使用spawn() ,在使用spawnSync()返回任何数据之前,子spawnSync()终止,承诺链尝试(并失败)在子spawnSync()产生之前监听子spawnSync() io

我还没有尝试websockets传输数据,但我怀疑这将解决这个问题,承诺是返回一个空的对象到我的路由器函数调用之前,承诺链检索从python脚本的块。

任何进一步的见解是受欢迎

所以你至less需要两件事来做到这一点

  • 排队命令以spawn执行的一种方法
  • 一个asynchronous模式,用于等待每个可执行文件终止时执行命令并联接进程

一个简约的例子是

 var cmd = new CommandLine({ debug : true, error : true, delay : true }); // commandItemsArray is a list of commands list, command options, command arguments commandItemsArray = [ ['ls','-l','./'], ['ls','-a','./'] ]; cmd.executeCommands( commandItemsArray , function(results) { console.log( results ); } , function(error) { console.log( error ); }); 

在npm上有几个包可以做到(search节点cli,命令行等),一个是使用Promise.all模式来实现第二个任务的一个节点命令 :

  function PromiseAll(items, block, done, fail) { var self=this; var promises = [], index=0; items.forEach(function(item) { promises.push( function(item,i) { return new Promise(function(resolve, reject) { return block.apply(this,[item,index,resolve,reject]); }); }(item,++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if(done) done( results ); }, function ErrorHandler(error) { if(fail) fail( error ); }); } //promiseAll 

我能够使用websockets相对简单地解决这个问题:

客户端提交通过socket.IO传递给服务器的请求,接收到请求并触发产生事件,当块完成时附加一个终止事件,触发杀死subprocess并返回数据给客户