node.js-按时附加事件处理程序
我正在学习node.js,在node.js手册中遇到了这个示例:node.js-按时附加事件处理程序,node.js,javascript-events,Node.js,Javascript Events,我正在学习node.js,在node.js手册中遇到了这个示例: ... var req = http.request(options); req.end(); req.on('upgrade', function(res, socket, upgradeHead) { console.log('got upgraded!'); socket.end(); process.exit(0); }); ... 我在这个例子中看到的是,在创建请求之后,甚至在(计划)发送请求之后,附加到
...
var req = http.request(options);
req.end();
req.on('upgrade', function(res, socket, upgradeHead) {
console.log('got upgraded!');
socket.end();
process.exit(0);
});
...
我在这个例子中看到的是,在创建请求之后,甚至在(计划)发送请求之后,附加到HTTP请求事件的处理程序。更糟糕的是,手册上说:
如果未侦听此事件,则接收升级标头的客户端将关闭其连接
事件是否可能在(…有机会附加处理程序之前发生?我怀疑我不了解节点的异步模型中的某些内容。或者,节点手册中的这段代码旨在希望网络请求比执行下一行代码花费更长的时间
另一个例子:
http.get("http://www.google.com/index.html", function(res) {
console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
在这里,HTTP请求将在对象创建后立即启动,我们只在创建后附加一个错误处理程序
网络延迟,(2)我不了解node.js概念,或者(2b)事件将“等待”直到我将处理程序附加到它
编辑:
更好的例子,也来自手动。下面的好例子和坏例子是不同的,只是因为在好例子中,我们附加事件的速度足够快,因此丢失数据的概率很低,或者永远不可能以这种方式丢失数据(为什么?!)
你错过的是JavaScript根本不是异步的!我的意思是JavaScript是单线程的,异步操作实际上不是异步的。有一个非常奇特的队列模型,它给人一种JavaScript异步的错觉(别误会:它仍然是最有效的模型) 那么这意味着什么呢?这意味着一旦同步代码运行,其他代码就不可能并行运行
var req = http.request(options);
req.end();
req.on(...);
已计划请求,但主线程(即操作)尚未在req.end()
处结束。只要主操作尚未完成,中间就不会触发异步代码。特别是,处理程序总是在实际事件发生之前设置
另一个例子让它更清楚一些。请考虑这个代码:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
while(true) { } // <------ infinite loop doing nothing
}).listen(1337, '127.0.0.1');
var http=require('http');
http.createServer(函数(req,res){
res.writeHead(200,{'Content-Type':'text/plain'});
res.end('Hello World\n');
虽然(正确){}/但要理解的关键是,只有一个事件循环,当您调用异步函数时,控件只保留事件循环的当前“滴答声”。通常在执行I/O(每隔几行代码是常见的)或调用setTimeout
/setInterval
(相当罕见)时会自然发生这种情况。因此,只要所有事件处理程序都注册在事件循环的同一个勾号内,您就不会丢失任何数据。此外,在事件循环的勾号内,附加处理程序的顺序无关紧要,因为在该勾号期间,您的代码实际上是节点执行的唯一内容,因此其他代码无法接收I/O或I/O在当前事件循环勾选完成之前,取消任何事件处理程序。这不是等待“足够长”或网络延迟或诸如此类的事情。是单个事件循环的简单性保证了事件处理程序函数的可预测操作。我假设使用.on()声明事件处理程序是同步的吗?否则,分配将被添加到请求后的队列中并结束。@Aejay是的,它是同步的。
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
while(true) { } // <------ infinite loop doing nothing
}).listen(1337, '127.0.0.1');