如何重试功能?

时间:2018-10-28 05:47:57

标签: javascript node.js promise generator

我正在开发满足个人需求的脚本。如果返回错误,我需要重试,但是我不知道如何解决。该怎么解决?

const request = require("request");
const co = require('co');


function init() {
  co(function *(){
    var res = yield GetData();
    console.log(res);
  });
}

function onerror(error) {
  console.log("error below");
  console.log(error);
  console.log(error.code);
  console.error(error.stack);
}

function send_request(options, callback){
  co(function *(){
    let RetryAttemptCount = 0;
    let MaxRetries = 3;

    let res;

    res = yield request(options, function (error, response, body) {
      var tmp;
      if (!body && error && !response) {
        RetryAttemptCount++;
        console.log('increase RetryAttemptCount :',RetryAttemptCount);
        throw new onerror(error);
      } else if (!error) {
        tmp = JSON.parse(body);
        return tmp;
      }
    });
  }).catch(onerror);
}

function GetData() {
  return new Promise(function(resolve, reject){
    var options = { method: 'GET', url: 'https://api.upbit.com/v1/market/all' };

    send_request(options, (res) => {
      resolve(res);
    });
  });
}

init();

但是出现以下错误:

  

TypeError:您只能产生一个函数,promise,生成器,数组,   或对象,但传递了以下对象:“ [对象对象]”

3 个答案:

答案 0 :(得分:1)

您可以使用简单的重试功能非常普遍地进行此操作:

async function retry(fn, attempts = 3, delay = 2000) {
   return async function(...args) {
     for(const i = 0; i < attempts; i++) {
       try {
         await fn.call(this, ...args); // delegate
       } catch (e) {
          if(attempts-- > 0) await new Promise(r => setTimeout(r, delay));
          else throw e;
       }
     }
   }
}

这可以让您做到:

let retried = retry(fn);
// ... then later

await retried({ ... params });

答案 1 :(得分:0)

我建议您使用requestretry npm代替请求。使用简单

var request = require('requestretry');

request({
url: 'https://api.domain.com/v1/a/b',
json: true,

// The below parameters are specific to request-retry
maxAttempts: 5,   // (default) try 5 times
retryDelay: 5000,  // (default) wait for 5s before trying again
retryStrategy: 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);
}
});

您可以通过更改maxAttempts值来控制重试计数

答案 2 :(得分:0)

由于@Benjamin的answer,我想出了这个经过修改的代码,该代码经过了简化,并添加了指数补偿功能。

☁  util [master] ⚡  go test -v -coverprofile cover.out
=== RUN   TestOsEnvFetcher
--- PASS: TestOsEnvFetcher (0.00s)
PASS
coverage: 80.0% of statements