我熟悉c ++和Java中基于事件的系统。我试图学习node.js并遇到了有趣的行为,我希望有人可以解释其背后的情况。
我有一个看起来像的程序
var http = require("http");
function main(){
// Console will print the message
console.log('Server running at http://127.0.0.1:8080/');
var server = http.createServer(function (request, response) {
// Send the HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// Send the response body as "Hello World"
response.end('Hello World\n');
});
server.listen(8080); //Why is this not blocking
console.log('Main completed');
//main loop here prevents other stuff from working
}
main();
在像Java或C这样的语言中,我期望两件事。server.listen都提供了一个事件循环,它将导致server.listen永不返回。或者server.listen产生一个新线程,并在返回的新线程中运行事件循环。然后它将调用console.log,然后返回并关闭该程序。
为了测试这一点,我还在console.log下面添加了一个忙循环,如下所示。
var http = require("http");
function main(){
// Console will print the message
console.log('Server running at http://127.0.0.1:8080/');
var server = http.createServer(function (request, response) {
// Send the HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// Send the response body as "Hello World"
response.end('Hello World\n');
});
server.listen(8080); //Why is this not blocking
console.log('Main completed');
while(true){
console.log('hi');
}
}
main();
Server.listen立即返回,然后按预期卡在繁忙循环中。我的浏览器无法连接到服务器,这是预期的。
如果我删除了繁忙的循环并回到原始代码,请执行console.log('Maincomplete');。当执行而不是退出程序时,主线程将跳回事件循环。
这是如何运作的。主线程返回后,为什么主线程跳回到服务器代码中?
编辑:我认为决议事件队列在主函数中不存在,但它在哪里?它是什么拥有的?什么时候主函数引用它?
认为http.createServer(handler)
与浏览器server.listen(port)
有点相似someElement.addEventListener('click', handler)
。
运行时someElement.addEventListener('click', handler)
,它将绑定事件侦听器,handler
当单击事件被触发时,该事件侦听器将发送到回调队列someElement
。
http.createServer(handler)
server.listen(port)
以非常相似的方式与工作结合。http.createServer(handler)
返回eventEmitter
,并server.listen(port)
告诉node.js当在给定端口上收到http请求时,应触发此事件。因此,当请求进入时,事件被触发,并handler
被推送到回调队列。
至此,仅是事件循环调用堆栈和回调队列如何交互的一个简单问题。该调用堆栈是函数当前执行的栈,该回调队列是回调等待执行的集合,而事件循环就是回调拉断的回调队列,并把它们发送到调用堆栈。
因此,从某种意义上说,事件循环可以使一切正常进行,但是,如果您通过在一个回调中使用同步无限循环来阻止调用栈为空,则事件循环将永远不会再次运行,并且回调也永远不会执行,从而导致损坏/无响应的应用程序。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句