San*_*an4 7 javascript-events node.js
我正在研究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);
});
...
Run Code Online (Sandbox Code Playgroud)
我在这个例子中看到的是,在创建请求之后,甚至在(计划发送)之后,处理程序附加到HTTP请求事件.更糟糕的是,手册说:
如果未侦听此事件,则接收升级标头的客户端将关闭其连接.
事件是否有可能在 req.on(...有机会附加处理程序之前发生?我怀疑我对节点异步模型中的某些内容并不了解.或者这个代码来自节点手册,希望网络请求比执行下一行代码需要更长的时间?
另一个例子:
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);
});
Run Code Online (Sandbox Code Playgroud)
这里,HTTP请求将在创建对象后立即启动,之后我们才会附加错误处理程序.同样,(1)它是一个仅因网络延迟而起作用的代码,(2)我没有得到关于node.js概念的东西,或者(2b)事件将"等待"直到我附加一个处理程序?
编辑:更好的例子,也来自手动.下面的好的和坏的例子是不同的,因为在好的例子中我们足够快地附加事件,因此错过数据的机会很少,或者永远不可能以这种方式错过数据(为什么?!)
// Good
request.on('response', function (response) {
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
// Bad - misses all or part of the body
request.on('response', function (response) {
setTimeout(function () {
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
}, 10);
});
Run Code Online (Sandbox Code Playgroud)
你想念的是JavaScript根本不是异步的!我的意思是JavaScript是单线程的,异步操作实际上并不是异步的.有一个非常奇特的队列模型,它给出了JavaScript异步的错觉(不要误解我:它仍然是最有效的模型).
那是什么意思呢?这意味着一旦同步代码运行,其他代码就不可能并行运行.例如,在此代码中
var req = http.request(options);
req.end();
req.on(...);
Run Code Online (Sandbox Code Playgroud)
请求已安排,但主线程(即操作)尚未结束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');
Run Code Online (Sandbox Code Playgroud)
请注意,第一个请求将成功完成.但任何其他请求永远不会得到回应.这是因为循环永远不会完成操作,因此JavaScript 无法跳转到另一个事件.这段代码永远崩溃了应用程序,超出了任何希望.所以要小心使用Node.js的同步代码.:)
| 归档时间: |
|
| 查看次数: |
1689 次 |
| 最近记录: |