Mr. Ant
Mr. Ant

Reputation: 700

Generic promise retry logic

I am trying to figure out how to create a generic retry function that exponentially backs off for any promise passed to it. It looks like everything is working except for a couple things. If the function resolves on the first try, then I see my resolve value and it logs out hey which is expected. If it resolves on any subsequent call, it does not log out hey. If it rejects, I get a couple deprecation warnings which I haven't looked into yet. Here is the code...

function retry(func, max, time) {
    console.log(max);
    return new Promise((resolve, reject) => {
        func()
            .then(r => resolve(r))
            .catch(err => {
                if (max === 0) {
                    reject(err);
                } else {
                    setTimeout(function(){
                        retry(func, --max, time * 2);
                    }, time);
                }
            });
    });
}

const promise = retry(function () {
    return new Promise((resolve, reject) => {
        const rand = Math.random();
        if (rand >= 0.8) {
            resolve('hey');
        } else {
            reject(new Error('oh noes'));
        }
    });
}, 5, 100);

promise.then(r => console.log(r)).catch(err => console.log(err));

Any help would be appreciated.

Upvotes: 2

Views: 187

Answers (1)

Orelsanpls
Orelsanpls

Reputation: 23505

Here is a working example

/**
 * Function to retry
 */
function retry(func, max, time) {
  return new Promise((resolve, reject) => {
    apiFunction()
      .then(resolve)
      .catch(err => {
        if (max === 0) {
          return reject(err);
        } else {
          setTimeout(function() {
            retry(func, --max, time * 2)
              .then(resolve)
              .catch(reject);
          }, time);
        }
      });
  });
}

/**
 * Function to test out
 */
const apiFunction = () => new Promise((resolve, reject) => {
  const rand = Math.random();

  if (rand >= 0.8) {
    console.log('Works');
    
    resolve('hey');
  } else {
    console.log('fail');
    
    reject(new Error('oh noes'));
  }
});

retry(apiFunction, 5, 10)
  .then(() => console.log('all done ok'))
  .catch(() => console.log('all done error'));

Upvotes: 1

Related Questions