我熟悉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();
Run Code Online (Sandbox Code Playgroud)
在像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();
Run Code Online (Sandbox Code Playgroud)
Server.listen立即返回,然后按预期陷入繁忙循环.我的浏览器无法连接到服务器,这是预期的.
如果我删除busy循环并返回原始代码,一旦console.log('Main completed'); 执行而不是程序退出,主线程跳回到事件循环.
这是如何运作的.为什么主线程返回后主线程会跳回到服务器代码中?
编辑:我认为重新解决了主要功能中不存在事件队列但它在哪里?拥有什么?什么时候主函数会参考它运行?
想想http.createServer(handler)并且在浏览器中server.listen(port)有点类似someElement.addEventListener('click', handler).
运行时someElement.addEventListener('click', handler),它会绑定一个事件侦听器,该事件侦听器将handler在触发click事件时发送到回调队列someElement.
http.createServer(handler)server.listen(port)以非常相似的方式结合工作.http.createServer(handler)返回一个eventEmitter,并server.listen(port)告诉node.js当在给定端口上收到http请求时,应该触发此事件.因此,当请求进入时,事件被触发,并handler被推送到回调队列.
此时,事件循环callstack和回调队列如何交互只是一个简单的问题.该调用堆栈是函数当前执行的栈,该回调队列是回调等待执行的集合,而事件循环就是回调拉断的回调队列,并把它们发送到调用堆栈.
因此,从某种意义上说,事件循环是保持一切运行的原因,但是,如果通过在其中一个回调中阻塞callstack使其无法循环,则事件循环永远不会再次运行并且回调永远不会被执行,从而导致破碎/反应迟钝的申请.
| 归档时间: |
|
| 查看次数: |
1034 次 |
| 最近记录: |