Почему Spawn () никогда не вызывается? - PullRequest
0 голосов
/ 26 мая 2020

У меня был некоторый опыт работы с node.js и express в течение некоторого времени, но я продолжаю сталкиваться с этой ошибкой в ​​моем коде. В моем служебном файле я вызываю spawn () внутри разрешенного обещания в моем коде. Почему-то мой код появления никогда не вызывается (или, если он вызывается, ls.on('close') или ls.on('error') никогда не вызывается), и я не знаю почему. Я думаю, что понимаю асинхронную природу Spawn(), но я думаю, что нет? ??‍♂️ Вот код из моего файла finalSendFiles.service.js:

const { spawn } = require('child_process');

const finalSendFiles = async (uVal) => {

    try {
        //new code
        console.log("I'm here")
        const getfirst_username = get_username(uVal);
        getfirst_username.then(function (username_value) {
            const pyScript = "./pythonFile.py"
            //spawn python file - this command ?? never gets called
            const ls = spawn('python', [pyScript, "./json_files/file1.json", "./json_files/file2.json", `${username_value}`])
            ls.on("error", (err) => {
                console.log(err)
            });

            ls.on("close", (code) => {
                console.log("You're done with the file!");
                console.log(`child process exited with code ${code}`);
            });
        });
    } catch (error) {
        console.log(error)
    }
}

module.exports = {
    finalSendFiles
}

Буду признателен за любую помощь на пути вперед!

PS Два файла, которые необходимы для отправки, записываются в систему с использованием fs.writeFile(), поэтому эти файлы должны быть созданы до фактического выполнения спауна


Обновление (06 / 20.01): Я провел небольшое тестирование с использованием mocha. js и нашел несколько интересных результатов. Во-первых, когда я запускаю npm test в приведенном ниже коде, все проходит успешно.

test.js

describe('spawnFunc', function() {
  describe('#spawn()', function() {
    it('it should call the python script', function(done) {
      const pyScript = "./p1.py"
      const ls = spawn('python', [pyScript])

      ls.stdout.on('data', function(data){
        console.log(data.toString());
      }).on("close", (code) => {
        console.log("You're done with the .csv file bro!");
        console.log(`child process exited with code ${code}`);
        done()
      });
    });
  });

});

Вывод моего кода:

> mocha

  spawnFunc
    #spawn()
You've made it to the python file!

You're done with the .csv file bro!
child process exited with code false

Итак, мое тестирование каким-то образом работает . Однако, когда я делаю const ls = spawn('python', ["./p1.py"]) в своем обычном коде, он никогда не попадает в точку появления. Я уже пробовал python-shell, и это тоже не работает. Кажется, я столкнулся с той же проблемой здесь

Опять же, любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 26 мая 2020

Я вижу несколько возможностей:

  1. Обещание, которое возвращается get_username(), может в конечном итоге быть отклоненным. У вас нет обработчика .catch() для обнаружения и обработки этого.

  2. Кроме того, ваша функция finalSendFiles() вернется задолго до того, как операция spawn() будет выполнена, если это вас смущает.

Я подумал, что происходит что-то подобное. Да, мне нужно сначала вернуть spawn(), а затем finalSendFiles()

Ну, вы не можете предотвратить возвращение finalSendFiles() до того, как spawn() будет выполнено (это природа асинхронного logi c in Javascript), если вы не используете spawnSync(), который заблокирует весь ваш процесс во время операции spawnSync(), что обычно не является тем, что вы когда-либо хотели бы делать на сервере.

Если вы хотите сохранить асинхронная версия spawn(), то вам нужно будет вернуть обещание от finalSendFiles(), связанное с завершением вашей операции spawn(). Вы можете сделать это следующим образом:

const finalSendFiles = (uVal) => {
    console.log("I'm here")
    return get_username(uVal).then(function (username_value) {
        const pyScript = "./pythonFile.py"
        //spawn python file - this command ?? never gets called
        return new Promise((resolve, reject) => {
            const ls = spawn('python', [pyScript, "./json_files/file1.json", "./json_files/file2.json", `${username_value}`])
            ls.on("error", (err) => {
                console.log(err)
                reject(err);
            }).on("close", (code) => {
                console.log("You're done with the file!");
                console.log(`child process exited with code ${code}`);
                resolve(code);
            });
        });
    });
}

Примечание: ваш вызывающий абонент должен будет использовать обещание, которое он вернет, чтобы увидеть как завершение, так и ошибки, например:

finalSendfiles(...).then(code => {
    console.log(`Got return code ${code}`);
}).catch(err => {
    console.log(err);
});
...