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

Javascript Node.js-如果在I/O和回调仍在运行时调用response.end会发生什么?,javascript,node.js,Javascript,Node.js,在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() { myO

在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');
});
具体而言:

  • 在调用第一个response.end时,HTTP连接是否立即释放?(加分:我如何亲自检查?)
  • 我可以用它在myOtherFunc中执行任意复杂/昂贵的计算,甚至是同步计算吗?由于连接已被释放,客户端不再等待?(或者有什么理由不这样做吗?)
  • 这是否可以作为一种范例,在调用时执行“后台”任务,“myOtherFunc”是一个任意的后台任务——因为它现在基本上是在“后台”运行的
    调用response.end不会停止任何仍在执行的异步代码。如果您试图结束或修改已结束的响应,您可能会看到奇怪的行为。所以,基本上所有人都同意。不过我承认,我不是node在幕后如何处理其HTTP连接的专家。

    我没有测试过,但是:

  • 考虑到节点的异步性质,在调用第二个
    响应.end
    之前,流可能不会被释放,但我怀疑您能否依赖这一点。。。在某个时刻,连接必须关闭,尝试发送新数据“最多”会以静默方式失败
  • 连接已释放,客户端将不会等待。。。至少对于该请求,但代价高昂的同步计算将占用应用程序的其余部分,请停止。任何后续的请求都必须等待您的工作完成,如果您在接下来的几分钟内无法完成,则
    响应
    的可能性将消失
  • 了解有关节点的单线程性的详细信息。节点的工作方式不是一次做一堆事情,而是在等待时不阻塞。除非您显式生成自己的线程来执行某些操作,否则没有“背景”
  • 编辑:我假设
    响应
    流通过
    end
    调用显式关闭,而不是坐在那里等待垃圾收集。我的假设是,它只是异步完成的,而不是等待完成后继续,如果在事件循环的下两个周期内到达,它仍然可能被分配


    再次编辑:您勇敢的回答者不知疲倦地搜索了节点源,并确认,实际上,对
    end
    的两个调用确实不起作用,第二个应该短路

    您刚刚尝试过吗?当试图写入一个已经关闭的流时,我希望它会抛出一个错误。我确实尝试过,它似乎工作得很好。但是我可以删除第二个响应;问题仍然是一样的。所以re:你的链接,这意味着对#1的回答是“是”,第一个回复。结束连接?2.超级的。因此,改变问题的焦点-假设我删除了第二个remove.end(),我现在可以“自由地”使用此“后台”(即请求客户端已离开的后台)任务,同时理解它位于单线程上下文中,但能够运行进一步的非阻塞I/O操作吗?假设我的繁重操作是I/O,我可以使用这个范例(在回调之外运行response.end())来委托任务在请求结束后运行?我一直在寻找,没有看到流的明确释放,但我一直在寻找20分钟,我无法根据我所看到的给出一个明确的答案,但不管怎样,调用
    end
    显式设置一个
    finished
    属性,该属性阻止该流通过正常通道可用。您应该能够相当容易地进行测试,只需在回调中执行一些时间密集型操作,并查看客户端是否在服务器完成处理之前完成加载。关于您更改的焦点,请参阅下一条评论。如果我理解您的要求,那么是的,您可以在请求结束后使用回调来运行任务。通常,这将通过调用
    setImmediate
    或在事件循环的后续传递中调用代码的其他适当变体来完成(如果您还没有合法发生的异步操作,如
    fs.writeFile
    ,则希望在流程完成后运行该操作)。客户端不会等待回调完成,只需
    结束
    响应,并且不要干扰回调中的响应。谢谢,已接受。这不是一种处理启动繁重后台操作的请求的好方法吗?我可以释放客户机(和响应),说“我稍后再处理”,然后将操作委托给I/O+回调(在响应之后运行)。跨多个请求执行此操作是否会带来任何扩展问题?(为什么?)。HTTP通信必须由客户端发起,因此如果您完成对客户端的响应,然后稍后完成处理,则无法将该信息发送回客户端。这通常由处理,其中客户端在页面加载后发出ajax请求并等待响应。您希望避免在apache中进行长时间轮询,但node在这方面工作得非常好。