promise-retry Build Status Code Climate Test Coverage

Retry a function until its returned promise succeeds

“ var retryPromise = require(‘@songkick/promise-retry’); var retryTwiceEveryHundredMil = retryPromise({ retries: 2, delay: 100 });

retryTwiceEveryHundredMil(resolvesTheThirdTime)() .then(function(result){ // never called here, // but if retries was >= 3, // result would be === ‘yay!’ }).catch(function(err){ // err instanceof retryPromise.OutOfRetriesError === true // err === { // message: ‘Maximum retries count reached’, // settings: { // retries: 2, // }, // fn: resolvesTheThirdTime, // errors: [nope, nope, nope] // } });

var calls = 0; function resolvesTheThirdTime() { if (++calls < 3) { return Promise.reject(‘nope’); } else { return Promise.resolve(‘yay!’); } }

Options

retries: positive (>= 0) number. The initial call doesn’t count as a retry. If you set it to 3, then your function might be called up to 4 times.

delay: the delay between retries or a function(retryIndex){} returning the delay. Does not apply on initial call. If a function is passed, it will receive the retry index as first argument (1, 2, 3 ...).

Example:

“ var retryWithIncreasingDelay = retryPromise({ retries: 10, delay: function(retryIndex) { return 100 * retryIndex; });

/* time line:

0 > initial fail 0 + 100 > first retry 100 + 200 > second retry 300 + 300 > third retry 600 + 400 > fourth…

Composition

As promise-retry input and output is a function returning a promise, you can compose them easily:

“ var retryTwice = retryPromise({ retries: 2 }); var retryAterTwoSeconds = retryPromise({ retries: 1, delay: 2000 }); var getRejected = function(){ return Promise.reject(‘nope’); };

retryOnceAterTwoSeconds(retryTwice(getRejected))().then(function(){ // no way here }).catch(function(){ // at this point, getRejected will have been called 6 times });

In the above exemple, the getRejected, this will happen:

  1. Initial nest retry call
  2. initial getRejected call - callcount: 1
  3. first of two retries - callcount: 2
  4. second of two retries - callcount: 3
  5. wait 2000ms
  6. first and only retry
  7. initial getRejected call - callcount: 4
  8. first of two retries - callcount: 5
  9. second of two retries - callcount: 6
  10. final rejection

See also

promise-retry composes really well with the following promise helper: