在Javascript.Promise.reject上重试次数有限或直到成功

时间:2017-02-24 02:13:58

标签: javascript es6-promise

我有一个函数说myMainFunction从客户端调用,然后调用mypromisified函数。

情境: mypromisified函数可能会间歇性地失败,我需要延迟调用此函数(以指数增长)直到成功或直到达到最大尝试次数。

到目前为止我有什么

以下代码说明了我的方案,并重复直至成功,但它无限期地尝试,直到达到某些计数



// called once from the client
myMainFuntion();

function rejectDelay(delay, reason) {
   // call main function at a delayed interval until success 
   // but would want to call this only a limited no of times
    setTimeout(() => {
      myMainFuntion(); // calling main function again here but with a delay
    }, delay);
}


function myMainFuntion() {
  var delay = 100;
  var tries = 3;
  tryAsync().catch(rejectDelay.bind(null, delay));
}

function tryAsync() {
  return new Promise(function(resolve, reject) {
    var rand = Math.random();
    console.log(rand);
    if (rand < 0.8) {
      reject(rand);
    } else {
      resolve();
    }
  });

}
&#13;
&#13;
&#13;

while内的

rejectDelay循环肯定不会起作用,因为即使在执行setInterval中的实际函数之前计数器也会递增,所以我不确定如何解决这个问题?所以...

我尝试了promisifying setInterval这样的事情知道它会失败:(因为它不会减少计数器,但也不确定如何使其正确。

&#13;
&#13;
function rejectDelay(delay, maximumTries, reason) {
  return new Promise(function (resolve, reject) {
    console.log(tries + ' remaining');
    if (--maximumTries > 0) {
      setTimeout(function() {
        foo();
      }, 500);
    } 
  });
}
function myMainFunction() {
  var delay = 100;
  var maximumTries = 3;
  tryAsync().catch(rejectDelay.bind(null, delay, maximumTries));
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:9)

使用了一些我已经使用过的辅助函数,这变得非常容易

“助手”

Promise.wait = (time) => new Promise(resolve => setTimeout(resolve, time || 0));
Promise.retry = (cont, fn, delay) => fn().catch(err => cont > 0 ? Promise.wait(delay).then(() => Promise.retry(cont - 1, fn, delay)) : Promise.reject('failed'));

代码:

function myMainFuntion() {
      var delay = 100;
      var tries = 3;
      Promise.retry(tries, tryAsync, delay);
}
  

ES5版本的助手

Promise.wait = function (time) {
    return new Promise(function (resolve) {
        return setTimeout(resolve, time || 0);
    });
};
Promise.retry = function (cont, fn, delay) {
    return fn().catch(function (err) {
        return cont > 0 ? Promise.wait(delay).then(function () {
            return Promise.retry(cont - 1, fn, delay);
        }) : Promise.reject('failed');
    });
};