2

experienced programmer, inexperienced javascript programmer.

I am working with Node-RED and in one of my nodes, I am calling an external program with 'child_process' which sends data back to my node via stdout.

I am using console.info(stdout) to log the child process data, so I know that it is working appropriately. This is the code within the function node:

/* required modules */
var cp = context.global.child_process;

/* variables */
var packet = {};
var cmd = '~/packet/packet.py ';

/* construct the packet object */
packet.networkTime = (msg.payload[3] << 24) + (msg.payload[2] << 16) + (msg.payload[1] << 8) + msg.payload[0];
packet.sampleCount = msg.payload[4];
packet.uncompressedWidth = msg.payload[5];
packet.compressedWidth = msg.payload[6];

packet.sample0 = (msg.payload[8] << 8) + msg.payload[7];

var compressedData = msg.payload.slice(9);

/* change buffer type to array */
packet.compressedData = [];
compressedData.forEach(
    function(element){
        packet.compressedData.push(element);
    }    
);

/* stringify the object */
var packet_str = "'" + JSON.stringify(packet) + "'";

/* this section will execute the command */
cp.exec(
    cmd + packet_str,
    function(error, stdout, stderr){
        console.info(stdout);
        return JSON.parse(stdout);
    }
);

//return data_msg;

I tried setting data_msg to {} and using JSON.parse(stdout) to place into that object, but the 'return data_msg' always executes before the value is returned. I simply want to wait for my external process to return data before returning this node.

Thank you for your assistance,

2 Answers 2

1

Node.js has asynchronous execution. Put some things in functions and handle sequential execution in callbacks or use promises. Below is my use of promises that I use to ensure a scipt is finished executing before using it's stdout data within it's calling function.

Upon stderr the promise is rejected and an error message is propagated. Upon stdout data is stored in result. When the process finishes the data is returned as the promise is resolved.

var spawn = require('child_process').spawn;

anExecutable = function(cmd, packet_str){
  return new Promise(function(resolve, reject){

    var aProcess = spawn(cmd, packet_str);

    aProcess.stdout.on('data', (data) =>{
      var result = JSON.parse(data);
    });
    aProcess.on('error', (error) => {
      reject(error);
    });
    aProcess.on('exit', (code) => {
      resolve(result);
    });
  });
}

Call like this:

anExecutable(cmd, packet_str).then(function(data_msg){
  return data_msg;
}).catch(function(error){
  return error;
});

Let me know if you have any Q's :D

Sign up to request clarification or add additional context in comments.

Comments

0

Maybe you're looking for execSync?

1 Comment

I'm not ignoring you, I have just gotten distracted by a different issue. Thank you for the reference, I will try it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.