[英]How do I correctly make consecutive calls to a child process in Node.js?
I have a Node.js application which is currently a web-based API. 我有一个Node.js应用程序,该应用程序当前是基于Web的API。 For one of my API functions, I make a call to a short Python script that I've written to achieve some extra functionality.
对于我的API函数之一,我调用了一个简短的Python脚本,该脚本是为实现某些额外功能而编写的。
After reading up on communicating between Node and Python using the child_process
module, I gave it a try and achieved my desired results. 在阅读完使用
child_process
模块进行的Node和Python之间的通信后,我尝试了一下并取得了期望的结果。 I call my Node function that takes in an email address, sends it to Python through std.in
, my Python script performs the necessary external API call using the provided e-mail, and writes the output of the external API call to std.out
and sends it back to my Node function. 我调用接收电子邮件地址的Node函数,并通过
std.in
将其发送到Python,我的Python脚本使用提供的电子邮件执行必要的外部API调用,并将外部API调用的输出写入std.out
并将其发送回我的Node函数。
Everything works properly until I fire off several requests consecutively. 一切正常,直到我连续发出多个请求。 Despite Python correctly logging the changed e-mail address and also making the request to the external API with the updated e-mail address, after the first request I make to my API (returning the correct data), I keep receiving the same old data again and again.
尽管Python的正确记录更改的电子邮件地址,并发出请求,将更新的电子邮件地址的外部API,第一个请求我让我的 API后(返回正确的数据),我不断收到相同的旧数据一次又一次。
My initial guess was that Python's input stream wasn't being flushed, but after testing the Python script I saw that I was correctly updating the e-mail address being received from Node and receiving the proper query results. 我最初的猜测是没有清除Python的输入流,但是在测试Python脚本之后,我看到我正在正确地更新从Node接收的电子邮件地址并接收正确的查询结果。
I think there's some underlying workings of the child_process module that I may not be understanding... since I'm fairly certain that the corresponding data is being correctly passed back and forth. 我认为child_process模块的某些基础工作可能我不了解...因为我相当确定相应的数据已正确地来回传递。
Below is the Node function: 下面是Node函数:
exports.callPythonScript = (email)=>
{
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
return getPythonData;
}
And here is the Python script: 这是Python脚本:
import sys
from emailage.client import EmailageClient
def read_in():
lines = sys.stdin.readlines()
return lines[0]
def main():
client = EmailageClient('key','auth')
email = read_in()
json_response = client.query(email,user_email='authemail@mail.com')
print(json_response)
sys.stdout.flush()
if __name__ == '__main__':
main()
Again, upon making a single call to callPythonScript
everything is returned perfectly. 同样,在单次调用
callPythonScript
一切都会完美返回。 It is only upon making multiple calls that I'm stuck returning the same output over and over. 只有在进行多次调用时,我才能一遍又一遍地返回相同的输出。
I'm hitting a wall here and any and all help would be appreciated. 我在这里碰壁,任何帮助都将不胜感激。 Thanks all!
谢谢大家!
I've used a Mutex lock for this kind of example. 在这种示例中,我使用了互斥锁。 I can't seem to find the question the code comes from though, as I found it on SO when I had the same kind of issue:
我似乎找不到代码的问题,因为当我遇到类似问题时,我在SO上发现了它:
class Lock {
constructor() {
this._locked = false;
this._waiting = [];
}
lock() {
const unlock = () => {
let nextResolve;
if (this._waiting.length > 0) {
nextResolve = this._waiting.pop(0);
nextResolve(unlock);
} else {
this._locked = false;
}
};
if (this._locked) {
return new Promise((resolve) => {
this._waiting.push(resolve);
});
} else {
this._locked = true;
return new Promise((resolve) => {
resolve(unlock);
});
}
}
}
module.exports = Lock;
Where I then call would implement it like this, with your code: 然后我调用的地方将使用您的代码来实现它:
class Email {
constructor(Lock) {
this._lock = new Lock();
}
async callPythonScript(email) {
const unlock = await this._lock.lock();
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
await unlock();
return getPythonData;
}
}
I haven't tested this code, and i've implemented where i'm dealing with arrays and each array value calling python... but this should at least give you a good start. 我尚未测试此代码,并且已经实现了在处理数组和调用python的每个数组值的地方……但这至少应该为您提供一个良好的开端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.