Как установить переменную из child_process.exec()

#javascript #node.js #child-process

Вопрос:

У меня есть простая функция для запуска системного приложения из Интернета.

 server.route({
  method: 'POST',
  path: '/executeMain',
  handler: (req, res) => {
    var success = false;
    exec("./main", (error, stdout, stderr) => {
      if (error) {
        console.log('error: '   error.message);
        return;
      }
      if (stderr) {
        console.log('error: '   stderr);
        return;
      }
      console.log(stdout);
      success = true;
    });

    if (success) {
      return res.response("OK").code(200);
    }
    else {
      return res.response("ERR").code(500);
    }
  }
});
 

В функции exec я хочу установить значение success равным true, но этого никогда не происходит. Кто-нибудь может мне помочь и объяснить, почему это не работает.

Ответ №1:

child_process.exec() является асинхронной функцией. Таким образом, процесс начинает работать в фоновом режиме, и функция немедленно возвращается. Таким образом, вы проверяете значение success до завершения процесса и до того, как оно было установлено.

Ваш обработчик также должен быть асинхронным, поскольку он зависит от возвращаемого значения асинхронной функции. Что-то вроде:

 server.route({
  method: 'POST',
  path: '/executeMain',
  handler: (req, res) => {
    return new Promise( (resolve, reject) => {
        exec("./main", (error, stdout, stderr) => {
            if (error) {
                console.log('eror: '   error.message);
                reject( res.response("ERR").code(500) )
            }
            if (stderr) {
                console.log('error: '   stderr);
                reject( res.response("ERR").code(500) )
            }

            console.log(stdout);
            resolve( res.response("OK").code(200) )
        });
    });
}
 

С другой стороны, вы, вероятно, не хотите выдавать ошибку только потому stderr , что это правда. Многие программы пишут в stderr даже в случае успеха.

Комментарии:

1. Вам даже не нужно возвращать обещание и разрешать или отклонять его. Обратный вызов, переданный исполнителю, может просто записать результат, res.response(…).code(…) фактически вы ввели возможность отказа от необработанного обещания.