【发布时间】:2016-12-05 18:38:59
【问题描述】:
我试图了解幕后发生的事情 如果我尝试执行这个 NodeJS 代码:
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8081);
我有2个关于上述代码的案例:
1 .修改代码在最后一行做一些阻塞
http.createServer 回调函数:
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
sleep(2000); //sleep 2 seconds after handling the first request
}).listen(8081);`
//found this code on the web, to simulate php like sleep function
function sleep(milliseconds)
{
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++)
{
if ((new Date().getTime() - start) > milliseconds)
{
break;
}
}
}
我使用这个简单的 bash 循环向 NodeJS 服务器发出两个请求
$for i in {1..2}; do curl http://localhost:1337; done
客户端控制台上的结果:
Hello world#第一次迭代
两秒钟后,客户端控制台上会打印下一个 hello world
Hello world#第二次迭代
在请求的第一次迭代中,服务器可以立即响应请求。 但是在请求的第二次迭代中,服务器处于阻塞状态,并在两秒后返回对请求的响应。这是因为睡眠 处理第一个请求后阻塞请求的函数。
-
修改代码,而不是使用睡眠,我在
http.createServer回调函数的最后一行使用setTimeout。http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n'); setTimeout(function(){console.log("Done");}, 2000); }).listen(8081);`
我再次使用这个简单的 bash 循环来执行请求
for i in {1..2}; do curl http://localhost:1337; done
结果是响应立即返回给两个请求。
Hello world 消息也会立即打印在控制台上。
这是因为我使用的是 setTimeout 函数,它本身就是一个异步函数。
我对这里发生的事情有疑问:
1.我说对了吗:It is the responsibility for the programmer to make asynchronous call in NodeJS code so that the NodeJS internal can continue to execute other code or request without blocking.
2.NodeJS 内部使用Google V8 Engine 执行javascript 代码,使用libuv 执行异步操作。
事件循环负责检查事件队列中是否发生与回调相关的事件,并检查调用堆栈中是否有任何剩余代码,如果事件队列不为空且调用堆栈为空,则从事件回调队列被压入栈,导致回调被执行。
问题是:
A.在 NodeJS 中做异步事情时,回调函数的执行是否与 NodeJS 主线程中的代码执行分开(通过使用libuv 线程池)?
B.如果有多个连接同时到达服务器,Event Loop如何处理连接?
我会非常感谢每一个答案并尝试向他们学习。
【问题讨论】:
标签: node.js multithreading event-loop