我试图在超时或错误时自动重试HTTP请求。
目前我的代码如下:
var req = http.get(url, doStuff)
.on('error', retry)
.setTimeout(10000, retry);
但是,单个请求有时会触发错误"和"超时"事件。什么是实施重试的更好方法?
答案 0 :(得分:19)
我一直在寻找同样的东西,并找到了有趣的模块requestretry,非常适合这种要求。
以下是用法:
var request = require('requestretry')
request({
url: myURL,
json: true,
maxAttempts: 5, // (default) try 5 times
retryDelay: 5000, // (default) wait for 5s before trying again
retrySrategy: request.RetryStrategies.HTTPOrNetworkError // (default) retry on 5xx or network errors
}, function(err, response, body){
// this callback will only be called when the request succeeded or after maxAttempts or on error
if (response) {
console.log('The number of request attempts: ' + response.attempts);
}
})
答案 1 :(得分:5)
您可以尝试这样的事情:
function doRequest(url, callback) {
var timer,
req,
sawResponse = false;
req = http.get(url, callback)
.on('error', function(err) {
clearTimeout(timer);
req.abort();
// prevent multiple execution of `callback` if error after
// response
if (!sawResponse)
doRequest(url, callback);
}).on('socket', function(sock) {
timer = setTimeout(function() {
req.abort();
doRequest(url, callback);
}, 10000);
}).once('response', function(res) {
sawResponse = true;
clearTimeout(timer);
});
}
更新:在最近/现代版本的节点中,您现在可以指定一个timeout
选项(以毫秒为单位),用于设置套接字超时(在连接套接字之前)。例如:
http.get({
host: 'example.org',
path: '/foo',
timeout: 5000
}, (res) => {
// ...
});
答案 2 :(得分:1)
这是适合我的代码。关键是在超时后销毁套接字以及检查响应是否完成。
function httpGet(url, callback) {
var retry = function(e) {
console.log("Got error: " + e.message);
httpGet(url, callback); //retry
}
var req = http.get(url, function(res) {
var body = new Buffer(0);
res.on('data', function (chunk) {
body = Buffer.concat([body, chunk]);
});
res.on('end', function () {
if(this.complete) callback(body);
else retry({message: "Incomplete response"});
});
}).on('error', retry)
.setTimeout(20000, function(thing){
this.socket.destroy();
});
}
答案 3 :(得分:0)
使用请求承诺,为什么不在异步匿名函数中使用while循环:
(async () => {
var download_success = false;
while (!download_success) {
await requestpromise(options)
.then(function (response) {
download_success = true;
console.log(`Download SUCCESS`);
})
.catch(function (err) {
console.log(`Error downloading : ${err.message}`);
});
}
})();
还要注意,存在requestretry模块。