Merge Two codes

£可爱£侵袭症+ 提交于 2020-03-24 09:44:51

问题


I have 2 files in Node js .I want to merge these 2, but I am facing problem.. This file calls function from python file

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 file ml.py

def testMLFunction():
return "hello from Python"

print(testMLFunction())

Below file works on button click with post method

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);

how can I do that..


回答1:


There are several things wrong here. I will explain as plain as possible.

  1. You forgot to add in your code var express = require('express')
  2. The promise you made, runPy, must be wrapped in a function, whereas your approach will instantly start the promise upon loading the script itself.
  3. You are resolving/rejecting on first incoming output, you shouldn't do that because you won't be able to know what really happened in the shell. You need to store those output lines, this is the only way of you knowing what the script tells you.
  4. In runPy you must resolve/reject upon pyprogr close event.
  5. You cannot access directly the method of another script, no matter what that kind of file that is a py, sh, bat, js. However, you can access internal functions of it by passing arguments to the shell, and of course, that script must have the logic required to deal with those arguments.
  6. When using spawn/exec you must keep in mind that YOU ARE NOT the user executing the script, the node user is, so different outcomes may occur.
  7. Most importantly, your targeted script must PRINT/ECHO to shell, no returns! The best approach would be to print some json string, and parse it in javascript after the shell is closed, so you can have access to an object instead of a string.

Below you will find a demo for your use case, i changed the python file so it can print something.

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>


来源:https://stackoverflow.com/questions/60407826/merge-two-codes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!