Node JS,延迟响应

12
var http = require('http');
var s = http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.write('Hello\n');
      setInterval(function() {
          res.end(' World\n');
      },2000);
      console.log("Hello");
});
s.listen(8080);
在启动上述服务器后,我运行:
curl http://127.0.0.1:8080 

我获得了所需的延迟。输出:

Hello <2 seconds> World

但是在浏览器中,整个内容加载需要2秒钟。

Hell World <together after 2s>

我做错了什么?


1
提示: "res.end()" 生成一个完整的结果,该结果将呈现给浏览器。因此,一旦调用 end 方法,响应就会返回给浏览器。我知道这不是答案,但它可能有所帮助。 - Pranav
3个回答

18
下面的代码打开一个响应流并将其流式传输到客户端。因此,在curl中,您将先收到“Hello”,然后在2秒后收到“World”(因为您设置了2000毫秒的计时器)。
      res.write('Hello\n');
      setTimeout(function() {
          res.end(' World\n');
      },2000);

但是浏览器只有在完整的响应流接收到后才会渲染它。这就是为什么你在2秒后才收到响应。

这完全是浏览器的行为。它不会利用响应流,直到整个响应被接收。一旦流关闭,整个响应就会准备好被使用。然而,在PHP中有一种方法可以在需要时刷新响应流。

但是,如果你想经常流式传输数据,这不是最好的方法。我建议你使用Comet技术websockets

我希望这是你要找的内容。


但是在浏览器中是否有任何方法可以使用Node来伪造此功能? - Jayaram

10
// simulate delay response
app.use((req, res, next) => {
    setTimeout(() => next(), 2000);
});

这里使用了一个“中间件”,它可以捕获所有内容。以“if (dev) app.use(...);”模式插入任何应用程序更加容易。 - jehon

6

浏览器的行为与curl不同。浏览器将不会呈现页面,直到调用res.end()。所以,如果您想要延迟后加载网页的一部分,您需要通过websocket或ajax请求单独加载第二部分。我建议使用websocets。看看socket.io,这是在node.js中使用websocets的简单方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接