简体   繁体   English

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

[英]Node.js - what happens if I call response.end while I/O and callbacks are still running?

In Node.js, what happens if call "response.end()" while my I/O calls and/or callbacks are still executing?在 Node.js 中,如果在我的 I/O 调用和/或回调仍在执行时调用“response.end()”会发生什么? As in the following:如下所示:

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');
});

Specifically:具体来说:

  1. Is the HTTP connection freed up immediately upon calling the first response.end?调用第一个 response.end 时是否立即释放了 HTTP 连接? (Bonus points: how can I inspect this myself?) (加分项:我如何自己检查?)
  2. Can I use this to perform arbitrarily complex/costly computation, even synchronous ones, within myOtherFunc?我可以使用它在 myOtherFunc 中执行任意复杂/昂贵的计算,甚至是同步计算吗? Since the connection has been freed the client is no longer waiting?由于连接已被释放,客户端不再等待? (Or is there any reason why not?) (或者有什么理由不这样做?)
  3. Can this be used as a paradigm to perform 'background' tasks upon invocation, with 'myOtherFunc' being an arbitrary background task -- since it is essentially now running "in the background"?这可以用作在调用时执行“后台”任务的范例,“myOtherFunc”是一个任意的后台任务——因为它现在基本上是“在后台”运行的?

Calling response.end doesn't stop any asynchronous code that's still executing.调用 response.end 不会停止任何仍在执行的异步代码。 You'll might see weird behavior though if you try to end or modify a response that's already been ended.但是,如果您尝试结束或修改已经结束的响应,您可能会看到奇怪的行为。 So, basically yes to all.所以,基本上都是肯定的。 I'll admit though, I'm not an expert on how node handles its HTTP connections behind the scenes.不过我承认,我不是节点如何在幕后处理其 HTTP 连接的专家。

I haven't tested, but:我没有测试过,但是:

  1. Given the asynchronous nature of node, it's possible the stream wouldn't be freed up before the second response.end is called, but I doubt you can rely on that... at some point the connection must close and trying to send new data will "at best" fail silently.鉴于节点的异步性质,在调用第二个response.end之前可能不会释放流,但我怀疑您是否可以依赖它...在某些时候连接必须关闭并尝试发送新数据将“充其量”无声地失败。
  2. The connection is freed and the client won't be waiting... for that request, at least, but costly synchronous computations will hold up the rest of your application, full stop.连接被释放,客户端不会等待......至少对于该请求,但昂贵的同步计算将阻止应用程序的其余部分,完全停止。 Any subsequent requests will have to wait for your work to finish, and odds are response will be gone if you don't get to it by the next few ticks.任何后续的请求都必须等待您的工作完成,如果您在接下来的几个滴答声中没有得到response那么很可能就会消失。
  3. Learn more about node's single threadedness.了解有关节点单线程的更多信息。 node works not by doing a bunch of things at once, but by not blocking while it's waiting. node 的工作不是同时做一堆事情,而是在等待时不阻塞。 There is no "background" unless you explicitly spawn your own thread to do something.没有“背景”,除非您明确地产生自己的线程来做某事。

Edit: I'm working with the assumption that the response stream is closed explicitly, with the end call, rather than just sitting out there waiting to be garbage collected.编辑:我假设response流在end调用时显式关闭,而不是坐在那里等待垃圾收集。 My assumption is it's just done asynchronously rather than waiting on completion to continue on, and if you get there within the next couple ticks of the event loop, it may still be allocated.我的假设是它只是异步完成,而不是等待完成才能继续,如果您在事件循环的下几个滴答声中到达那里,它仍然可能被分配。

Edit Again: Your intrepid answerer has searched tirelessly through the node source and confirmed that, indeed, two calls to end should indeed not work, the second should be short circuited by the OutgoingMessage.finished property (see lines 499-501 and 541)再次编辑:您勇敢的回答者不知疲倦地搜索了节点源并确认,实际上,两个end调用确实应该不起作用,第二个调用应该被OutgoingMessage.finished属性短路(参见第 499-501 和 541 行)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM