我正在从文本文件中读取 ID 并发出一些 RESTful 请求。它可以工作,但是当所有 ID 都已运行时, Node 应用程序将保持运行状态。
main.js:
var fs = require('fs');
var http = require('http');
var ids = fs.readFileSync('test.txt', { encoding: 'utf8' });
ids = ids.split('\n');
var options = {
hostname: 'internalhost',
port: 80,
path: '',
method: 'DELETE'
};
for (var i = 0; i < ids.length; i++) {
options.path = '/thing/' + ids[i];
console.log('Deleting thing ' + ids[i]);
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
});
req.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
req.end();
}
请求已成功发出,但在最后一个请求之后,应用程序继续运行。我尝试在打印响应的状态代码后立即添加 res.end()
,但随后出现错误,指出 res
没有方法 结束
。
这是怎么回事?
最佳答案
看来您是suffering from a side-effect of HTTP keep-alives 。当有 TCP 连接打开时, Node 不会退出,并且 HTTP Agent
无限期地保持 TCP 连接打开。
您提到保持事件对您有利,因此您的选择有限。
仅禁用
代理
将导致保持事件状态被禁用,因此这实际上不是一个选项。您可以手动管理和跟踪您的请求,所有请求完成后,调用
process.exit
。然而,我不喜欢这个,因为它是一个相当生硬的工具。如果您正在运行其他异步操作(例如数据库调用),您可能会在这些操作完成之前意外结束您的应用。您可以手动管理和跟踪您的请求。全部完成后,您可以循环访问
Agent
实例的sockets
属性并关闭所有延迟的套接字。 (警告:callingclose
on an already closed socket throws。)这是一种更安全的方法,因为其他未完成的操作将被允许在应用程序退出之前完成。
您可以升级到 Node ≥ 0.11.4。 (实际上,您可能需要等到 0.12 稳定版本发布。)下一个 Node 版本有 greatly improved
Agent
implementation那unref
s 空闲套接字保留在Agent
的连接池中。换句话说,如果唯一打开的 TCP 连接是那些被保留以作为保持事件连接重用的连接,则 Node 可以退出。您还可以撕掉 new
Agent
implemention来自不稳定分支,并将其用于您的应用程序的请求,而不是您的 Node 版本提供的默认Agent
。 (这可能就是我会做的。)
关于node.js - Node 应用程序在网络请求后不会终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23701176/