这是另一个SO线程的后续问题:
NodeJs how to create a non-blocking computation
就像那个问题的作者一样,我试图围绕如何与node.js异步编码,并且在练习时最终得到了非常相似的代码。
main.js
var http = require("http");
var url = require('url');
http.createServer(function (request, response) {
var path = url.parse(request.url).pathname;
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('Hello ');
switch(path) {
case '/people':
var people = require('./child');
people.speak(response);
break;
default:
response.write('World');
break;
}
response.end();
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
child.js
module.exports = {
speak: function (response) {
sleep(5000);
response.write('People');
}
};
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e14; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
就像那段代码的作者一样,我偶然发现主要事件线程在等待child.js响应时不会对新请求开放。这是当我来到stackoverflow并发现我需要fork一个新的子进程。但是,从主线程执行此操作将意味着新节点将为每个访问者#34; / people&#34;进行调整。这看起来非常低效,本文明确指出: https://nodejs.org/en/docs/guides/dont-block-the-event-loop/
您不应该只是为每个客户创建一个子进程。您可以比创建和管理子项更快地接收客户端请求,并且您的服务器可能会成为一个分叉炸弹。
我想做文章推荐的内容:使用工作池。我如何通过建立我已有的东西来实现这一目标(而不是像文章所说的那样获得附加组件)?
奖金问题[修改]: 似乎node.js最适用于可能遇到大等待时间或具有大量I / O的程序。 async-I / O允许程序员在等待响应(来自外部进程或用户)时处理请求,但缺少工作池意味着由于处理循环导致的程序响应延迟将阻止程序(除非你剥离了一个子进程)。我的理解是否更准确?
更新:
回归基础后,我现在明白了我犯的一个根本错误。 Node.js从I / O角度来看是异步的,但不是处理立场。上面的代码在测试时似乎是阻塞的。但是,这不是因为无法监听新请求,而是因为child.js中的sleep函数锁定了程序(有一个进程线程而没有工作池,所以这么大的循环锁定了程序)。
这可以通过这个新版本的main.js来证明(本演示中不需要child.js):
var http = require("http");
var url = require('url');
http.createServer(function (request, response) {
var path = url.parse(request.url).pathname;
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('Hello ');
switch(path) {
case '/people':
setTimeout(function () {
response.end('People');
},5000);
break;
default:
response.end('World');
break;
}
}).listen(8081);
这次,感觉使用了适当的延迟(与流程密集型循环相反),程序能够处理多个请求。但是,让我们说我确实有一个过程密集的步骤,真正需要大约5秒才能完成,我想在node.js中写这个。我需要在单独的线程上运行此代码。并且,如前所述,我们希望避免为每个客户端请求创建新线程,而是依赖于工作池。有没有办法在node.js中执行此操作,而不必依赖任何C / C ++加载项或扩展?