Search code examples
javascriptnode.jsecmascript-6promisees6-promise

How to Retry a Promise in ES6


I've been trying to figure out how to best implement retrying e.g. a failed download using promises. My best guess is to resolve a promise with a new promise (see the pseudocode below), but all I could find in the documentation is that Promise.resolve() can be called with a thenable (and so, I believe, with a Promise). Does this apply to the resolve callback in the promise constructor as well? Is my approach correct or is there a better way to implement a retry?

function getdata(url) {
   return new Promise(function(resolve, reject) {
      ajaxcall({
         url: url,
         success: function(data) { resolve(data); },
         failure: function(err) { 
            if(retriable(err)) {
               resolve(getdata(url));
            }
            else {
               reject(err);
            }
         }
      });
   });
}

Solution

  • Your approach would work. When a promise is passed to the resolve callback of the Promise constructor, the resolution value of that promise is used as the resolution value of the "outer" promise.

    It could be cleaner to wrap ajaxcall in a promise-returning function so that you're not mixing and matching promise and callback paradigms.

    function fetch(url) {
      return new Promise(function(resolve, reject) {
        ajaxcall({
          url: url,
          success: resolve,
          failure: reject
        });
      });
    }
    
    function getdata(url) {
      return fetch(url)
        .catch(function(err) {
          if(retriable(err)) {
            return getdata(url); // or fetch(url) to retry only once
          } else {
            throw err;
          }
        });
    }