首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >writeHead是否是非阻塞IO命令?

writeHead是否是非阻塞IO命令?
EN

Stack Overflow用户
提问于 2013-05-20 15:13:04
回答 3查看 288关注 0票数 0

我正在编写一段代码来为客户端加载页面。其中的一段代码是:

代码语言:javascript
复制
response.writeHead(301, {"Location": "/login/index.html"});
response.end("");

问题是,如果我有一个名为A的慢速客户端,这段代码是否会阻止其他客户端的事件循环?或者它可以在A等待页面加载时处理其他事件?

我在一本书中读到,最好使用管道方法,就像下面的代码:

代码语言:javascript
复制
var fs = require('fs');
var rs = fs.createReadStream('/login/index.html');
rs.pipe(response);

使用哪一个更好?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-20 19:14:33

正如@spotirca已经指出的,response.writeHead()不是缓存的,但我认为值得在这个问题的另一个方面展开讨论,即pipe()的使用。

pipe()在这里实际上是一个转移注意力的问题,问题是重定向是使用现有的HTTP响应还是开始一个新的周期。重要的是要理解这两种解决方案做的事情完全不同。

301重定向

代码语言:javascript
复制
response.writeHead(301, {"Location": "/login/index.html"});
response.end("");

这使用永久重定向来响应浏览器,即告诉浏览器当前的应该总是重定向到指定的URL。如果您根据用户的会话状态将用户重定向到登录页面,那么这绝对是错误的,因为浏览器有理由缓存重定向并导致不受欢迎的行为。

流式传输

代码语言:javascript
复制
require('fs').createReadStream('/login/index.html').pipe(response);

这是可行的,但这意味着无论当前URL是什么,登录页面都将被提供。你也会打破标准的HTTP行为,在同一个URL上提供不同的内容,所以@spotirca指出,这会对缓存产生影响。

我的建议

使用302 (临时)重定向到/login/,然后从那里提供内容。

代码语言:javascript
复制
response.writeHead(302, {"Location": "/login/"});
response.end("");

我从不在URL中包含文件扩展名,因为这会降低您以后更改内容的能力,但这种方法的这一方面意味着您需要有一个请求处理程序来侦听该URL并提供静态文件。为此,您可以使用pipe()并设置合适的缓存头,但我的建议是使用Express或类似的框架来避免与自定义代码相关的but。

例如:

代码语言:javascript
复制
// A framework will do most of this for you
response.writeHead("Expires","Thu, 01 Dec 2994 16:00:00 GMT"); 
require('fs').createReadStream('/login/index.html').pipe(response);
票数 1
EN

Stack Overflow用户

发布于 2013-05-21 02:39:04

不,writeHead不占用I/O。它不从网络/磁盘读取或写入。它只是写入response (http.ServerResponse对象),该对象驻留在内存中。您创建/发送的每个响应都是一个单独的对象。每个响应只能调用一次,这样writeHead就不会阻塞。http.ServerResponse实现了一个用于同步的Writable Stream接口。

为了回答你的问题,它不能阻止客户端加载页面,不像SQL查询需要排序/序列化,writeHead需要简单的同步。

您已经读取的管道()方法当然更好,但只是在同步文件读取和较少文件读取方面。如果执行同步的readFileSync,将强制磁盘读取,并将阻塞节点服务器的其余部分的执行。所以如果你使用它,你就不能在读取文件时执行任何事情(做一些有意义的事情)。

但是要说你确实在用它。然后,对于每个请求,将从磁盘异步读取文件,但如果文件没有更改,则不需要这样做。将其读取到内存中一次,然后将其用于进一步的请求是明智的。对于静态文件,最好使用只在磁盘上发生更改时才执行读操作的缓存。

因此,最好使用像express那样的静态文件服务器。参见this

票数 2
EN

Stack Overflow用户

发布于 2013-05-20 15:30:54

不,writeHead不是同步的,它不会阻塞事件循环。我不建议在这个特定的例子中使用管道。我有两个原因:

  1. /login/index.html,是一个静态文件,可以缓存,因此降低了网络传输。非常有用,特别是对于速度较慢的客户端connections.
  2. Consistency:,登录url总是相同的。但这是品味问题:)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16644398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档