节点:等待python脚本运行

时间:2017-11-15 05:09:18

标签: javascript python node.js express asynchronous

我有以下代码。我首先上传文件,然后我读取文件,console输出如console.log(obj)。但响应首先出现,python脚本在场景后面运行。 如何让代码等待python脚本运行然后继续?

router.post(`${basePath}/file`, (req, res) => {

    //Upload file first

    PythonShell.run('calculations.py', { scriptPath: '/Path/to/python/script' }, function (err) {
        console.log(err);
        let obj = fs.readFileSync('Path/to/file', 'utf8');
        console.log(obj);
    });

    return res.status(200).send({
        message : 'Success',
    });
});

我无法获得console.log(obj);输出,因为它在响应后运行。 如何让它等待python脚本运行并在控制台上输出console.log(obj)

1 个答案:

答案 0 :(得分:4)

要在某些异步操作后返回结果,您应该在完成回调中调用res.send

router.post(`${basePath}/file`, (req, res) => {

    //Upload file first

    PythonShell.run('calculations.py', { scriptPath: '/Path/to/python/script' }, function (err) {
        console.log('The script work has been finished.'); // (*)
        if(err) {
          res.status(500).send({
            error: err,
          });
          console.log(err);
          return;
        }
        let obj = fs.readFileSync('Path/to/file', 'utf8');
        console.log(obj); // (**)
        res.status(200).send({
            message : 'Success',
        });
    });
});

然后,如果您在控制台中看不到日志(*),则表示该脚本无法正常工作或运行不正常。回调未被调用。首先,您需要确保脚本(PythonShell.run)正常工作并且正在调用回调。 POST处理程序将一直等到你调用res.send(没有任何延迟值),因此回调是主要的一点。

readFileSync也可能失败。如果readFileSync失败,您应该看到异常。如果没问题,那么您将看到下一个日志(**)并将发送响应。

我在您的代码中看到了PythonShell。我没有经验,但经过一些阅读后,我认为问题可能在于你如何使用它。它似乎是python-shell npm包,所以按照它的文档,你可能会尝试为你的脚本实例化一个python shell,然后使用监听器:

let pyshell = new PythonShell('calculations.py');

router.post(`${basePath}/file`, (req, res) => {
  pyshell.send(settings); // path, args etc
  pyshell.end(function (err) {
    console.log('The script work has been finished.');
    if(err) { res.status(200).send({ error: err }); }
    else { res.status(200).send({ message : 'Success' }); }
  });
});

这种方法可能更合适,因为pyton shell在不同的POST请求之间保持打开状态。这取决于您的需求。但我想它并没有解决脚本运行的问题。如果您确定脚本本身没问题,那么您只需要在Node环境中正确运行它。有一些要点:

  • 脚本路径
  • 参数
  • 其他设置

尝试删除所有参数(创建一些新的测试脚本),清理设置对象(仅保留路径)并从Node执行它。在Node中处理其结果。您应该能够通过正确的路径运行最简单的脚本!研究如何设置正确的scriptPath。然后在脚本中添加一个参数并使用参数运行它。 Hanlde再次结果。没有many options,但它们中的每一个都可能是不正当呼叫的原因。