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

Jay*_*aya 4 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();
    }
  });

}
Run Code Online (Sandbox Code Playgroud)

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

我尝试过这样promisifyingsetInterval事情,知道它会失败:(因为它不会减少计数器,但不知道如何使它正确.

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));
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*a X 11

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

"助手"

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'));
Run Code Online (Sandbox Code Playgroud)

代码:

function myMainFuntion() {
      var delay = 100;
      var tries = 3;
      Promise.retry(tries, tryAsync, delay);
}
Run Code Online (Sandbox Code Playgroud)

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');
    });
};
Run Code Online (Sandbox Code Playgroud)