Javascript 节点:等待python脚本运行

Javascript 节点:等待python脚本运行,javascript,python,node.js,express,asynchronous,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' }

我有以下代码。首先上传文件,然后读取文件和
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)
输出。

要在异步操作后返回结果,应该在完成的回调中调用
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
。我没有这方面的经验,但经过一些阅读后,我认为问题可能在于你如何使用它。它似乎是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' }); }
  });
});
这种方法可能更合适,因为pytonshell在不同的POST请求之间保持打开状态。这取决于你的需要。但我想这并不能解决脚本运行的问题。如果您确信脚本本身没有问题,那么只需要在节点环境中正确运行它。有几点:

  • 脚本路径
  • 论据
  • 其他设置

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

尝试移动
res.status(200)。在第三个
PythonShell.run
参数回调的主体末尾发送
。此操作将在脚本完成后发送200响应。是否要在该POST请求上响应脚本的运行结果?您在控制台输出中看到
console.log(obj)
的结果了吗?@dhilt否我在控制台中看不到
console.log(obj)
的输出。我想将响应作为
console.log(obj)
的输出返回。好的,我刚刚尝试给出一个答案。从代码中我只能看到
let obj=fs.readFileSync('Path/to/file','utf8')不工作,请检查文件是否有内容或文件,如果没有内容,则这将是一个错误。请调试一次。很好的解释,这很有意义,但是上面的代码不会返回响应,也不会在控制台中显示任何类型的消息或输出。从邮递员发送请求后,使用一个按预期保存在本地的文件等,除了每次调用后的路由名称之外,我什么都没有得到,这很好。这意味着
PythonShell.run
不起作用。恐怕我对这样的脚本运行一无所知,这超出了我的能力范围。您需要调试
PythonShell.run
call。我也这么认为。我使用
PythonShell.run
运行的脚本很好,因为我使用该脚本创建的文件正在创建,python部分工作正常
fs.readFileSync
用于读取存在的文件,该文件在PythonShell.run()之外工作,但不在其内部工作。