Node.js - 如果我在 I/O 和回调仍在运行时调用 response.end 会发生什么



在 Node.js 中,如果我的 I/O 调用和/或回调仍在执行时调用 "response.end()"会发生什么?如下:

var app = http.createServer(function(request, response) {
    response.writeHead(200, { 'Content-Type': 'text/plain'});
    fs.writeFile('baz', 'contents', function() {
                  myOtherFunc();
                  response.end('Second response.end'); 
    }); 
   response.end('First response.end');
});

具体说来:

  1. HTTP 连接是否在调用第一个响应后立即释放。end?(奖励积分:我如何自己检查?
  2. 我可以使用它在myOtherFunc中执行任意复杂/昂贵的计算,甚至是同步计算吗?由于连接已释放,客户端不再等待?(或者有什么理由不呢?
  3. 这可以用作在调用时执行"后台"任务的范例,而"myOtherFunc"是一个任意的后台任务 - 因为它现在基本上是在"后台"运行?

我还没有测试过,但是:

  1. 鉴于节点的异步性质,在调用第二个response.end之前可能无法释放流,但我怀疑您可以依赖它......在某些时候,连接必须关闭,尝试发送新数据"充其量"会以静默方式失败。
  2. 连接已释放,客户端将不会等待...至少对于该请求,但昂贵的同步计算将阻止应用程序的其余部分,句号。 任何后续请求都必须等待您的工作完成,如果您在接下来的几个刻度之前没有到达它,response的可能性就会消失。
  3. 详细了解节点的单线程性。 节点的工作原理不是一次做一堆事情,而是在等待时不阻塞。 没有"背景",除非你明确地生成自己的线程来做某事。

编辑:我正在假设response流通过end调用显式关闭,而不仅仅是坐在那里等待垃圾回收。我的假设是它只是异步完成的,而不是等待完成继续,如果你在事件循环的下一个几个刻度内到达那里,它可能仍然会被分配。

再次编辑:您勇敢的应答器不知疲倦地搜索了节点源,并确认确实,对end的两个调用确实不起作用,第二个应该被OutgoingMessage.finished属性短路(请参阅第 499-501 和 541 行)

调用 response.end 不会停止任何仍在执行的异步代码。 但是,如果您尝试结束或修改已结束的响应,您可能会看到奇怪的行为。所以,基本上是肯定的。 不过,我承认,我不是节点如何在幕后处理其HTTP连接的专家。

最新更新