Невозможно получить доступ к массиву из child_process в node.js - PullRequest
0 голосов
/ 06 августа 2020

Я хотел бы создать массив, затем добавить к нему результат data порожденного child_process, затем использовать этот массив в обратном вызове child_process.stdout.on('end',...).

Первоначально я пытался это:

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

Это привело к ошибке, Cannot read property 'push' of undefined.

Итак, я решил создать глобальную переменную, чтобы убедиться, что переменная будет доступна. Итак, я сделал это:

    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]
      ...
    });

Сначала казалось, что он работает, затем я обнаружил, что иногда он вылетает, так же, как и раньше, с Cannot read property 'push' of undefined.

Дополнительная информация

Итак, я вернулся к нему сегодня, и теперь он вылетает из-за другой ошибки.

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

Как указано в комментариях, он вылетает из-за var dataOut = dataCache[proc].join('');. Никакой код не изменился. Ошибка очень похожа, Cannot read property 'join' of undefined.

Также какое-то время sh вообще не срабатывал. Так что это определенно очень непоследовательно.

Кроме того, я определяю dataCache на ранней стадии скрипта, в глобальном пространстве имен, с простым объявлением, dataCache = {}

Ответы [ 2 ]

0 голосов
/ 16 августа 2020

Я нашел ответ, хотя не знаю, почему исходные попытки не сработали. Поскольку я использую этот шаблон несколько раз в одном и том же скрипте, я решил сжать его, чтобы мне было легче работать с ним, и только это исправило его.

Итак, я создал специальную функцию который запустил child_process и объединил все в одну функцию, например:

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

Затем я заменил код, который у меня был ранее, т.е.

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

, на:

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

Почему-то работает. Я предполагаю, что по какой-то причине мои переменные удалялись до того, как они использовались какой-то функцией asyn c delete. Возможно, стоит отметить, что весь этот код (за исключением объявления переменной dataCache и const { spawn } = require('child_process');) находился внутри socket.on('join',function(data){...});, что может иметь отношение к переменным, которые иногда непоследовательно исчезают перед их использованием.

0 голосов
/ 06 августа 2020

Вы сначала объявляете

let dataCache = []; 

?

В противном случае вы получите указанную ошибку.

Невозможно прочитать свойство 'pu sh' of undefined

Поскольку массив еще не определен.

Итак, сначала объявите массив, тогда вы можете сделать что-то вроде этого

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

Для вашего случая это будет выглядеть примерно так ..

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