我对node.js和express有一定的经验,已经有一段时间了,但是我的代码中一直遇到这个bug。在我的服务文件中,我在我的代码中的已解决的 Promise 中调用 spawn() 。不知为何,我的 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
}
如果有任何帮助,我将感激不尽!
P.S.需要发送的两个文件都是用写到系统中的 fs.writeFile()
所以这些文件需要在产卵实际执行之前完成。
更新(060120)。我用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
而这也是行不通的。我似乎也遇到了这个问题 此处
再次感谢任何帮助
我认为有几种可能。
承诺... get_username()
返回可能最终会被拒绝。你没有一个 .catch()
处理程序来检测和处理。
另外,您的 finalSendFiles()
函数将在 spawn()
操作是做的,万一这也是你困惑的地方。
我猜到了这样的事情是怎么回事。是的,我需要
spawn()
先回finalSendFiles()
嗯,你不能阻止 finalSendFiles()
前返回 spawn()
就完成了(这就是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);
});