Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Nodejs http重试超时或出错_Node.js_Http - Fatal编程技术网

Node.js Nodejs http重试超时或出错

Node.js Nodejs http重试超时或出错,node.js,http,Node.js,Http,我正在尝试在超时或出错时自动重试HTTP请求当前我的代码如下所示: var req = http.get(url, doStuff) .on('error', retry) .setTimeout(10000, retry); function doRequest(url, callback) { var timer, req, sawResponse = false; req = http.get(url

我正在尝试在超时或出错时自动重试HTTP请求
当前我的代码如下所示:

var req = http.get(url, doStuff)
              .on('error', retry)
              .setTimeout(10000, retry);
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);
            });
}

但是,单个请求有时会触发“出错”和“超时”事件。实现重试的更好方法是什么?

您可以尝试以下方法:

var req = http.get(url, doStuff)
              .on('error', retry)
              .setTimeout(10000, retry);
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);
            });
}
更新:在node的最新/现代版本中,您现在可以指定一个
超时
选项(以毫秒为单位),用于设置套接字超时(在连接套接字之前)。例如:

http.get({
 host: 'example.org',
 path: '/foo',
 timeout: 5000
}, (res) => {
  // ...
});

这就是对我有效的代码。关键是在超时后销毁套接字,并检查响应是否完成

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

我在寻找同样的东西,发现有趣的模块,非常适合这样的要求

用法如下:

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

使用请求承诺,为什么不在异步匿名函数中使用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}`);                      
        });
    }
})();

还请注意,存在一个模块。

@Holf不知道,我只是回答了这个问题,因为我认为这个模块是上述问题的完美解决方案。我使用了这个模块,它工作得很好。是的,我也发现它是一个完美的解决方案。感谢分享,这是一个完美的解决方案,无需重新发明轮子。