如何正确地连续调用 Node.js 中的子进程?
How do I correctly make consecutive calls to a child process in Node.js?
我有一个 Node.js 应用程序,目前是基于网络的 API。对于我的 API 函数之一,我调用了一个简短的 Python 脚本,该脚本是我为实现一些额外功能而编写的。
在阅读了使用 child_process
模块在 Node 和 Python 之间进行通信之后,我尝试了一下并取得了我想要的结果。我调用接收电子邮件地址的 Node 函数,通过 std.in
将其发送到 Python,我的 Python 脚本使用提供的电子邮件执行必要的外部 API 调用,并将外部 API 调用的输出写入 std.out
并将其发送回我的节点函数。
一切正常,直到我连续发出几个请求。尽管 Python 正确记录了更改后的电子邮件地址,并使用更新后的电子邮件地址向外部 API 发出请求,但在我向 my[= 发出第一个请求后38=] API(返回正确的数据),我不断收到相同的旧数据。
我最初的猜测是 Python 的输入流没有被刷新,但是在测试 Python 脚本后我发现我正确地更新了从节点并接收正确的查询结果。
我认为 child_process 模块的某些基本工作原理我可能不理解...因为我 相当 确定相应的数据正在正确地来回传递。
下面是节点函数:
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;
}
这里是 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()
同样,在对 callPythonScript
进行 单次 调用后,一切都完美返回。只有在进行多次调用时,我才会一遍又一遍地返回相同的输出。
我在这里碰壁了,我们将不胜感激。谢谢大家!
我在此类示例中使用了互斥锁。我似乎找不到代码来自的问题,因为当我遇到同样的问题时,我在 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;
然后我调用的地方将使用您的代码实现它:
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;
}
}
我没有测试过这段代码,我已经实现了处理数组的地方,每个数组值调用 python...但这至少应该给你一个好的开始。
我有一个 Node.js 应用程序,目前是基于网络的 API。对于我的 API 函数之一,我调用了一个简短的 Python 脚本,该脚本是我为实现一些额外功能而编写的。
在阅读了使用 child_process
模块在 Node 和 Python 之间进行通信之后,我尝试了一下并取得了我想要的结果。我调用接收电子邮件地址的 Node 函数,通过 std.in
将其发送到 Python,我的 Python 脚本使用提供的电子邮件执行必要的外部 API 调用,并将外部 API 调用的输出写入 std.out
并将其发送回我的节点函数。
一切正常,直到我连续发出几个请求。尽管 Python 正确记录了更改后的电子邮件地址,并使用更新后的电子邮件地址向外部 API 发出请求,但在我向 my[= 发出第一个请求后38=] API(返回正确的数据),我不断收到相同的旧数据。
我最初的猜测是 Python 的输入流没有被刷新,但是在测试 Python 脚本后我发现我正确地更新了从节点并接收正确的查询结果。
我认为 child_process 模块的某些基本工作原理我可能不理解...因为我 相当 确定相应的数据正在正确地来回传递。
下面是节点函数:
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;
}
这里是 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()
同样,在对 callPythonScript
进行 单次 调用后,一切都完美返回。只有在进行多次调用时,我才会一遍又一遍地返回相同的输出。
我在这里碰壁了,我们将不胜感激。谢谢大家!
我在此类示例中使用了互斥锁。我似乎找不到代码来自的问题,因为当我遇到同样的问题时,我在 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;
然后我调用的地方将使用您的代码实现它:
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;
}
}
我没有测试过这段代码,我已经实现了处理数组的地方,每个数组值调用 python...但这至少应该给你一个好的开始。