我对从child_process.fork()获取结果然后响应客户端感到困惑。 Node.js服务器在执行时是否能够响应更多请求,即,当child_process仍处于执行状态时,用户可以向服务器发送任何其他请求,并且用户能够获得最新请求的响应,是否正确? / p>
参考代码:
router.route('/analysis')
.get(function(req, res, next){
User.find({}, {'_id': true, 'are_you': true})
.exec(function(err, user){
if(err) return next(err);
var child = child_process.fork(__dirname + '/analysis.js', [], {});
child.send('Hi');
child.on('message', message => {
console.log('message from child:', message);
});
res.status(200).json(user); //does here client puts other requests in event queue, until the child process executes completely and responds?
});
});
答案 0 :(得分:2)
让我们通过关键线:
var child = child_process.fork(__dirname + '/analysis.js', [], {});
这一行告诉Node你想要fork并返回ChildProcess
来表示该动作。然而,实际的分叉还没有发生,因为它是异步执行的。它不会等待这种情况发生,你的代码将继续运行。
child.send('Hi');
同样没有任何事情立即发生,这只会将消息排队以发送到分叉进程。 send
方法应该返回true
以表示您的邮件已成功添加到队列中,但不保证它实际上会被传递。如果您需要反馈消息是否通过您,则需要将回调传递给send
。这都是异步的,所以你的代码再次继续运行下一行而不是等待。
child.on('message', message => {
console.log('message from child:', message);
});
这会在message
上注册ChildProcess
事件的监听器。注册会立即发生,但在继续运行代码之前,它不会等待收到消息(要清楚,回调中的代码不会被运行,直到收到消息为止,现在它将被跳过,并在下一行继续执行)。请记住,分叉还没有实际发生,您所做的只是与代表即将创建的子进程的ChildProcess
对象进行交互。同样,一切都是异步的,所以代码继续运行到下一行。
res.status(200).json(user);
发送对当前请求的响应。子进程仍然没有产生,它正在排队等待代码结束。就Express而言,请求现已完成,客户端(即浏览器)将很快收到响应。但是,这并不意味着将丢弃子进程。一旦Node有机会产生该过程,任何消息或事件都应该像您没有响应请求那样继续进行。你唯一能做的就是再次回应。
您在ChildProcess
上执行的所有操作都是异步的,因此他们实际上没有立即执行任何操作,他们只是排队等待做的事情'。正如当前编写的那样,您的代码将在子进程生成之前响应HTTP请求。如果您想在从子进程中获得一些结果后发送响应,那么您必须移动代码以发送您的响应,以便它在回调中以发送{{{ 1}}。
关于您同时进入的多个请求的问题,完全可能发生这种情况,并且可以同时分叉多个子进程。如果您的子进程无法应对同时运行多个副本(例如,因为它们都需要写入同一个文件),那么您需要防止自己发生这种情况,Node不会为您执行此操作