简体   繁体   中英

Cannot access array from child_process in node.js

I would like to create an array, then append to the array with the data output of a spawned child_process , then use that array in an child_process.stdout.on('end',...) callback.

Originally I was trying this:

    const { spawn } = require('child_process');
    var proc = spawn('php',[APIFile, phpParams]);
    var dataRet = [];
    proc.stdout.on('data', (stdout) => {
      dataRet.push(stdout);
    });
    proc.stdout.on('end', (stdout) => {
      ...
      // Do something with dataRet
      ...
    });

That was resulting in the error, Cannot read property 'push' of undefined .

So, I decided to make a global variable to make sure the variable would be accessible. So, I did this:

    const { spawn } = require('child_process');
    var proc = spawn('php',[APIFile, phpParams]);
    dataCache[proc] = [];
    proc.stdout.on('data', (stdout) => {
      dataCache[proc].push(stdout);
    });
    proc.stdout.on('end', (stdout) => {
      ...
      // Do something with dataCache[proc]
      ...
    });

It seemed to be working at first, then I discovered it sometimes crashes, the same way as before, with Cannot read property 'push' of undefined .

More information

So I came back to it today and now it's crashing on a different error.

    const { spawn } = require('child_process');
    var proc = spawn('php',[APIFile, phpParams]);
    dataCache[proc] = [];
    proc.stdout.on('data', (stdout) => {
      dataCache[proc].push(stdout);
    });
    proc.stdout.on('end', (stdout) => {
      ...
      var dataOut = dataCache[proc].join('');// It's crashing here
      ...
    });

As is commented, it's crashing on var dataOut = dataCache[proc].join('');. No code has changed. The error is very similar, Cannot read property 'join' of undefined .

Also for a while it didn't crash at all. So it's definitely very inconsistent.

Also, I do define dataCache early on in the script, in the global namespace, with a simple declaration, dataCache = {}

Are you declaring

let dataCache = []; 

first?

If not you will get the mentioned error.

Cannot read property 'push' of undefined

Because the array is not defined yet.

So declare the array first then you can do something like this

 let dataCache = []; const obj = { ["owl"]: "Are nice creatures" } dataCache.push(obj) console.log(dataCache)

For your case it will look something like this..

let dataCache = [];
proc.stdout.on("data", (stdout) => {
  const obj = {
    [proc]: stdout,
  };
  dataCache.push(obj);
});

I found an answer, although I do not know why the original attempts didn't work. Because I use this pattern several times in the same script, I decided to condense it so I could work on it more easily, and that alone fixed it.

So, what I did, was to create a special function that ran the child_process and consolidated everything into one function, like this:

function runPHPProcess(APIFile,phpParams,callbackFinished,callbackError,callbackClose){
  var proc = spawn('php',[APIFile, phpParams]);
  var retData = [];
  proc.stdout.on('data', (stdout) => {
    retData.push(stdout);
  });
  proc.stdout.on('end', () => {
    var stdout = retData.join('');
    callbackFinished(stdout);
  });
  proc.stderr.on('data', (data) => {
    if(typeof callbackError != "undefined")
      callbackError(data);
    console.error("there was an error: "+data.toString('utf8'));
  });
  proc.on('close', (code) => {
    if(typeof callbackClose != "undefined")
      callbackClose(data);
    console.log(`child process exited with code ${code}`);
  });
}

I then replaced the code I had earlier, ie

    var proc = spawn('php',[APIFile, phpParams]);
    dataCache[proc] = [];
    proc.stdout.on('data', (stdout) => {
      dataCache[proc].push(stdout);
    });
    proc.stdout.on('end', (stdout) => {
      ...
      var dataOut = dataCache[proc].join('');// It's crashing here
      ...
    });

with:

runPHPProcess(APIFile,phpParams,function(stdout){...});

For some reason it works. I guess for some reason, my variables were being deleted before they were being used, by some kind of async delete function. It may be work noting that all of that code (except the dataCache variable declaration and the const { spawn } = require('child_process'); ) was inside of a socket.on('join',function(data){...}); , which may have to do with the variables inconsistently sometimes disappearing before their use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM