Home > Mobile >  How to send data from child process back to parent using Spawn in NodeJS
How to send data from child process back to parent using Spawn in NodeJS

Time:12-24

I'm trying to run a python script from NodeJS using the spawn child process. I'm able to successfully get python to run and see the data using console log, but can not send the actual data back to the parent function so that I can use it elsewhere.

This the "Child.js" file where spawn is being called in Node.js:

//Child.js:  Node.js file that executes a python script using spawn...

function run_python_script(jsonString, callback){

    //spawn new child process to call the python script
    const {spawn} = require('child_process');
    const python = spawn('python3', ["-c",`from apps import python_app; python_app.run(${jsonString});`]);

    var dataToSend = ''
    python.stdout.on('data', (data) => {
        dataToSend = data.toString() //<---How do I return this back to other functions?
        return callback(dataToSend)  //<---this is not returning back to other functions.
    })

    python.stderr.on('data', (data)=>{
            console.log(`stderr: ${data}`)
        })
    }

module.exports = { run_python_script };

===================================================================== This is the file that calls the "Child.js" file above where I want to receive the data from Python back...

const Child = require('./Child.js');

const callback = (x)=>{return x} //<--simply returns what's put in

let company_data = {
    "industry": "Financial Services",
    "revenue": 123456789
}
jsonString = JSON.stringify(company_data);

let result = ''
result = Child.run_python_script(jsonString, callback) //<-- I want the results from python to be stored here so I can use it elsewhere. 

console.log(result) //<--this returns "undefined".  Data isn't coming back

CodePudding user response:

If you don't need to spawn the Python process asynchronously, then you can use spawnSync instead of spawn to directly get an object containing its stdout and stderr as strings:

const { spawnSync } = require('child_process');
const python = spawnSync('python3', ['-c', `print("hello"); assert False`], { encoding: "utf8" });

// Access stdout
console.log(python.stdout)

// Access stderr
console.log(python.stderr)

CodePudding user response:

I figured this out. I wrapped the entire spawn routine in a Promise

// child.js

function run_python_script(jsonString){

    const promise = new Promise((resolve, reject) => {
    
        // spawn new child process to call the python script
        const {spawn} = require('child_process');
    
        const python = spawn('python3', ["-c",`from apps import python_app; python_app.run(${jsonString});`])

        var dataToSend = ''
        python.stdout.on('data', (data) => {
            dataToSend = data.toString()
        })

        python.stderr.on('data', (data)=>{
            console.log(`stderr: ${data}`)
            reject(new Error(`stderr occured`))
        })

        python.on('close', (code)=>{
            if (code !=0){
                reject(new Error(`error code: ${code}`))
            }else{
                resolve(dataToSend)
            }
        })
    })

    return promise
}

module.exports = { run_python_script };

============================================================================ And here is the parent function which calls the child function above:

//Parent.js

const Child = require('./Child.js');

var data = {
    "industry": "Financial Services",
    "revenue": 12345678
}

var jsonString = JSON.stringify(data);

var result = ''
Child.run_python_script(jsonString).then(returnedData => {
    var result = returnedData;
    console.log(result)
})
.catch(err => {
    console.log(err)
})
  • Related