gpt4 book ai didi

javascript - setInterval 是否阻塞?

转载 作者:搜寻专家 更新时间:2023-10-31 23:53:51 26 4
gpt4 key购买 nike

我有以下 Node 应用程序

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() {

});

我正在使用它在我的客户端应用程序中使用服务器端事件。当我浏览到 http://localhost:8081/api/time它立即开始返回。如果我在另一个浏览器窗口中打开 URI,那么它需要几秒钟才能响应,但是它可以正常工作。

所以我的问题是 setInterval 阻塞,或者对于性能不佳还有其他解释吗?基于this answer它不应该是,但我不认为 constructSSE 会花费 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 个在 Node 上的服务器发送事件网络上找到的不同示例,它们都遇到了同样的问题。

我不认为 node.js 不适合这项任务。

我试过了

  1. 使用 process.nextTick
  2. 增加间隔
  3. 使用 setTimeout 而不是 setInterval
  4. 使用 express.js 或仅使用 node.js
  5. 使用一些 Node 模块,如 connect-ssesse-stream

我正要开始使用 webworker-threads 进行测试或 cluster module或其他服务器平台试图确定问题,然后我想到编写一个小页面来使用 EventSource API 获取事件。当我这样做时,一切正常,此外,在之前使用 Chrome 的测试中,我看到在网络选项卡中,SSE 请求包含一个名为 EventStream 的附加选项卡,但内容为空,即使数据定期到达。

这让我相信可能是浏览器没有以错误的方式正确解释请求,因为它是使用地址栏而不是 EventSource API 请求的。我不知道这是什么原因,但我举了一个小例子,绝对没有表现不佳。

我这样修改了你的代码。

  1. 添加了另一条到网站根目录的路由以进行测试

    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);
    });
  2. 创建了一个 index.html 文件

    <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>

{编辑}

我还想指出,感谢@Rodrigo Medeiros,使用 curl/api/time 发出请求并没有表现不佳,这强化了以下观点是浏览器相关的问题。

关于javascript - setInterval 是否阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31031922/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com