合并两个代码

Merge Two codes

我在 Node js 中有 2 个文件。我想合并这 2 个,但我遇到了问题.. 此文件从 python 文件

调用函数
const app = express()

let runPy = new Promise(function(success, nosuccess) {

    const { spawn } = require('child_process');
    const pyprog = spawn('python', ['./ml.py']);

    pyprog.stdout.on('data', function(data) {

        success(data);
    });

    pyprog.stderr.on('data', (data) => {

        nosuccess(data);
    });
});

app.get('/', (req, res) => {

    res.write('welcome\n');

    runPy.then(function(testMLFunction) {
        console.log(testMLFunction.toString());
        res.end(testMLFunction);
    });
})
app.listen(4000, () => console.log('Application listening on port 4000!'))

python 文件 ml.py

def testMLFunction():
return "hello from Python"

打印(testMLFunction())

以下文件适用于使用 post 方法点击按钮

var fs = require('fs');

var server = http.createServer(function (req, res) {

    if (req.method === "GET") {
        res.writeHead(200, { "Content-Type": "text/html" });
        fs.createReadStream("./form.html", "UTF-8").pipe(res);
    } else if (req.method === "POST") {

        var result = "";
        req.on("data", function (chunk) {
            console.log(chunk.toString());

            result = chunk;
            //body=body.toUpperCase;
        });

        req.on("end", function(){
            res.writeHead(200, { "Content-Type": "text/html" });
            res.end(result);
        });
    }

}).listen(3000);

我该怎么做..

这里有几处错误。我尽量解释清楚。

  1. 您忘记在代码中添加 var express = require('express')
  2. 您做出的承诺 runPy 必须包装在一个函数中,而您的方法将在加载脚本本身时立即启动承诺。
  3. 您是 resolving/rejecting 第一个传入输出,您不应该这样做,因为您将无法知道 shell 中到底发生了什么。您需要存储这些输出行,这是您了解脚本告诉您的唯一方法。
  4. runPy 中,您必须 resolve/reject 在 pyprogr 关闭 事件时。
  5. 你不能直接访问另一个脚本的方法,不管是py,sh,bat,js那种文件。但是,您可以通过将参数传递给 shell 来访问它的内部函数,当然,该脚本必须具有处理这些参数所需的逻辑。
  6. 当使用 spawn/exec 时,您必须记住您不是执行脚本的用户,node 用户才是,因此可能会出现不同的结果。
  7. 最重要的是,你的目标脚本必须PRINT/ECHO到shell,没有returns!最好的方法是打印一些 json 字符串,并在 shell 关闭后在 javascript 中解析它,这样您就可以访问对象而不是字符串。

下面你会找到一个 demo 用于你的用例,我更改了 python 文件以便它可以打印一些东西。

ml.py

print('I\'m the output from ml.py')

index.js

const express = require('express');
const app = express()

let runPy = function () { // the promise is now wrapped in a function so it won't trigger on script load
    return new Promise(function (success, nosuccess) {

        const {spawn} = require('child_process');
        const pyprog = spawn('python', ['./ml.py'], {shell: true}); // add shell:true so node will spawn it with your system shell.

        let storeLines = []; // store the printed rows from the script
        let storeErrors = []; // store errors occurred
        pyprog.stdout.on('data', function (data) {
            storeLines.push(data);
        });

        pyprog.stderr.on('data', (data) => {
            storeErrors.push(data);
        });
        pyprog.on('close', () => {
            // if we have errors will reject the promise and we'll catch it later
            if (storeErrors.length) {
                nosuccess(new Error(Buffer.concat(storeErrors).toString()));
            } else {
                success(storeLines);
            }
        })
    })
};

let path = require('path');
app.use(express.json());
app.use(express.urlencoded({ extended: true })); // you need to set this so you can catch POST requests
app.all('/', (req, res) => { // i've change this from .get to .all so you can catch both get and post requests here

    console.log('post params', req.body);

    if(req.body.hasOwnProperty('btn-send')){

        runPy()
            .then(function (pyOutputBuffer) {

                let message = 'You sent this params:\n' +JSON.stringify(req.body, null,2) + '\n';
                message += Buffer.concat(pyOutputBuffer).toString();

                res.end(message);

            })
            .catch(console.log)
    }else{
        res.sendFile(path.join(__dirname,'form.html')); // you need an absolute path to 'file.html'
    }

});
app.listen(4000, () => console.log('Application listening on port 4000!'));

form.html

<div>hello there</div>
<form action="/" method="post">
    <input type="text" value="" name="some-text"/>
    <button type="submit" value="1" name="btn-send" >Press me!</button>
</form>