在 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');
});
具体说来:
- HTTP 连接是否在调用第一个响应后立即释放。end?(奖励积分:我如何自己检查?
- 我可以使用它在myOtherFunc中执行任意复杂/昂贵的计算,甚至是同步计算吗?由于连接已释放,客户端不再等待?(或者有什么理由不呢?
- 这可以用作在调用时执行"后台"任务的范例,而"myOtherFunc"是一个任意的后台任务 - 因为它现在基本上是在"后台"运行?
我还没有测试过,但是:
- 鉴于节点的异步性质,在调用第二个
response.end
之前可能无法释放流,但我怀疑您可以依赖它......在某些时候,连接必须关闭,尝试发送新数据"充其量"会以静默方式失败。 - 连接已释放,客户端将不会等待...至少对于该请求,但昂贵的同步计算将阻止应用程序的其余部分,句号。 任何后续请求都必须等待您的工作完成,如果您在接下来的几个刻度之前没有到达它,
response
的可能性就会消失。 - 详细了解节点的单线程性。 节点的工作原理不是一次做一堆事情,而是在等待时不阻塞。 没有"背景",除非你明确地生成自己的线程来做某事。
编辑:我正在假设response
流通过end
调用显式关闭,而不仅仅是坐在那里等待垃圾回收。我的假设是它只是异步完成的,而不是等待完成继续,如果你在事件循环的下一个几个刻度内到达那里,它可能仍然会被分配。
再次编辑:您勇敢的应答器不知疲倦地搜索了节点源,并确认确实,对end
的两个调用确实不起作用,第二个应该被OutgoingMessage.finished
属性短路(请参阅第 499-501 和 541 行)
调用 response.end 不会停止任何仍在执行的异步代码。 但是,如果您尝试结束或修改已结束的响应,您可能会看到奇怪的行为。所以,基本上是肯定的。 不过,我承认,我不是节点如何在幕后处理其HTTP连接的专家。