return JSON 从 python 通过 spawn 到节点

return JSON from python to node via spawn

我有一个带有两个参数的 python 脚本;目录和文件名。

python 脚本将从提供的目录中的特定文件创建一个 JSON object,并将其保存为第二个参数的名称。

然而,如果第二个参数等于字符串 "stream",JSON 数据将输出到 STDOUT。

我编写了一个节点脚本,它生成了一个 child 进程来从终端调用 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());
    }
});

编辑:

我没有将这个问题标记为已解决:在花了更多时间尝试实现它之后,我还没有找到一个令人满意的解决方案,允许我从节点同步调用 child 进程,向python 脚本发出 JSON 数据,接收数据,然后将数据发送到浏览器。我尝试在 child 过程中使用承诺链:

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() child 在返回任何数据之前终止 使用 spawnSync() 承诺链尝试(但失败)在 child 生成

之前监听 child 的 io

我还没有尝试使用 websockets 来传输数据,但我怀疑这会解决这个问题,在承诺链从 python脚本。

欢迎任何进一步的见解。

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

客户端提交请求,该请求通过socket.IO与服务器通信,接收到请求并触发生成事件,当块完成附加时发出终止事件,触发终止事件子进程并将数据返回给客户端

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

  • 一种使用spawn
  • 排队执行命令的方法
  • 等待命令执行并在每个可执行文件终止时加入进程的异步模式

一个极简主义的例子是

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 上有几个包可以同时完成这两个任务(搜索节点 cli、命令行等),其中一个 node-commander 使用 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