Javascript 是间隔阻塞吗?
我有以下节点应用程序Javascript 是间隔阻塞吗?,javascript,node.js,event-loop,Javascript,Node.js,Event Loop,我有以下节点应用程序 var express = require("express"), app = express(); app.get("/api/time", function(req, res) { sendSSE(req, res); }); function sendSSE(req, res) { res.set({ "Content-Type": "text/event-stream", "Cache-Control":
var express = require("express"),
app = express();
app.get("/api/time", function(req, res) {
sendSSE(req, res);
});
function sendSSE(req, res) {
res.set({
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Access-Control-Allow-Origin": "*"
});
var id = (new Date()).toLocaleTimeString();
setInterval(function() {
constructSSE(res, id, (new Date()).toLocaleTimeString());
}, 5000);
constructSSE(res, id, (new Date()).toLocaleTimeString());
};
function constructSSE(res, id, data) {
res.write("id: " + id + "\n");
res.write("data: " + data + "\n\n");
}
var server = app.listen(8081, function() {
});
我正在使用它与我的客户端应用程序一起使用服务器端事件。当我浏览到它开始立即返回。如果我在另一个浏览器窗口中打开URI,那么它将需要几秒钟的时间才能做出响应,但是它工作正常
所以我的问题是setInterval阻塞,或者对于性能差有其他解释吗?基于这一点,它不应该是,但我不希望constructse
需要5秒钟。然而,我看到了一个问题
谢谢
更新
有人建议它可能与express
有关,我删除了它,只使用了http
模块
var http = require("http");
http.createServer(function(req, res){
if (req.url == "/api/time") {
sendSSE(req, res);
}
}).listen(8081);
function sendSSE(req, res) {
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Access-Control-Allow-Origin": "*"
});
var id = (new Date()).toLocaleTimeString();
setInterval(function() {
constructSSE(res, id, (new Date()).toLocaleTimeString());
}, 5000);
constructSSE(res, id, (new Date()).toLocaleTimeString());
};
function constructSSE(res, id, data) {
res.write("id: " + id + "\n");
res.write("data: " + data + "\n\n");
};
它有完全相同的行为。因此,这看起来像是Node的一些限制,或者是我的一个错误。我认为性能不佳的原因与Node或setInterval本身无关,而是与您读取事件数据的方式有关。我做了一些搜索,并实现了3或4个不同的例子,这些例子都是在web上发现的服务器在节点上发送事件,它们都面临着相同的问题 我认为node.js不适合这个任务,这不符合我的想法 我试过了
var express = require("express"),
app = express();
// Send an html file for testing
app.get("/", function (req, res, next) {
res.setHeader('content-type', 'text/html')
fs.readFile('./index.html', function(err, data) {
res.send(data);
});
});
app.get("/api/time", function(req, res) {
sendSSE(req, res);
});
<head>
<title>Server-Sent Events Demo</title>
<meta charset="UTF-8" />
<script>
document.addEventListener("DOMContentLoaded", function () {
var es = new EventSource('/api/time'),
closed = false,
ul = document.querySelector('ul');
es.onmessage = function (ev) {
var li;
if (closed) return;
li = document.createElement("li");
li.innerHTML = "message: " + ev.data;
ul.appendChild(li);
};
es.addEventListener('end', function () {
es.close()
closed = true
}, true);
es.onerror = function (e) {
closed = true
};
}, false);
</script>
</head>
<body>
<ul>
</ul>
</body>
服务器发送事件演示
document.addEventListener(“DOMContentLoaded”,函数(){
var es=new EventSource('/api/time'),
关闭=错误,
ul=文件查询选择器(“ul”);
es.onmessage=函数(ev){
李华;
如果(关闭)返回;
li=document.createElement(“li”);
li.innerHTML=“消息:”+ev.data;
ul.儿童(li);
};
es.addEventListener('end',函数(){
结束()
关闭=真
},对);
es.onerror=函数(e){
关闭=真
};
},假);
我还想指出,感谢@Rodrigo Medeiros,使用
curl
请求/api/time
,没有表现出性能差,这强化了这是一个与浏览器相关的问题的想法。我浏览[URI]和“我在另一个浏览器窗口中打开URI”之间的区别是什么,setInterval
确实没有阻塞。可能您遇到了res
的一些缓冲行为,需要刷新输出?Bergi。我的意思是,当原始连接仍然打开时,我发出第二个请求。@RodrigoMedeiros这不是重复的。您引用的问题使对其他资源的请求过快,而这是关于服务未完成的请求。虽然问题的原因可能与此相关,但解决方案并非如此。您无法减少此问题中的请求数,因为根本没有请求。我增加了间隔,问题依然存在。您在浏览器开发工具的“网络”选项卡中看到了什么?有数据吗?非常感谢你的帮助。这是有道理的,打卷发没有任何问题。@baynezy不客气。我试图将chrome配置为使用http/1.0来检查这是否与RFC 2616第8节中所述的http/1.1持久连接有关,以提供更准确的答案,但我无法这样做。找不到相应的chrome设置:(