In javascript, a function that returns a promise and repeats the best practice of an internal asynchronous process

I have a function that returns a javascript Promise, and some asynchronous code is executed inside it. Asynchronous code must be repeated multiple times if it fails. I did this until I saw some strange behavior that made me wonder if I was doing this the right way. So I had to change it. Both approaches are cut off here. I have an idea why the first approach (asyncFunc) is not working, I would appreciate it if someone could share some technical clarity on this. And for the second approach (ayncFunc_newer) any suggestion on how this can be done better?

var _retryCount = 0;

// this is what I was doing
function asyncFunc () {
	return new Promise(function(fulfill, reject) {
		doAsync()
			.then(fulfill)
			.catch(retry);

		function retry(promiseResult) {
			if(_retryCount < 3) {
				_retryCount++;
				return asyncFunc();
			}
			else {
				reject(promiseResult);
			}
		}
	});
}

// this what I'm doing now
function ayncFunc_newer() {
    return new Promise(function(fulfill, reject) {
        var retryCount = 0;

        doAsync()
            .then(fulfill)
            .catch(onReject);

        function onReject(bmAuthError) {
            if(retryCount < 3) {
                retryCount++;
                logWarning(error);
                
                doAsync()
                	.then(fulfill)
                	.catch(onReject);
            }
            else {
                fulfill(false);
            }
        }
    });                 
};
      

Run codeHide result


+3


source to share


1 answer


The best practice is to avoid the constructor promise constructor . Basically, new Promise

there is mainly for porting non-promise APIs, so if your functions are already returning promises, then there is usually a way to avoid using it.

If you are doing retries with a small amount of fixed numbers, your case will be as simple as:

function ayncFunc() {
  return doAsync().catch(doAsync).catch(doAsync).catch(doAsync);
};

      

For a custom number of repetitions, you can expand this:

var retries = 3;

function ayncFunc() {
  var p = doAsync();
  for (var i = 0; i < retries; i++) {
    p = p.catch(doAsync);
  }
  return p;
};

      



Or for more tries, you can use a recursive approach:

function ayncFunc() {
  function recurse(i) {
    return doAsync().catch(function(e) {
      if (i < retries) {
        return recurse(++i);
      }
      throw e;
    });
  }
  return recurse(0);
};

      

var console = { log: msg => div.innerHTML += msg + "<br>" };

function doAsync() {
  console.log("doAsync");
  return Promise.reject("Nope");
}

function ayncFunc() {
  return doAsync().catch(doAsync).catch(doAsync).catch(doAsync);
};

var retries = 3;

function ayncFunc2() {
  var p = doAsync();

  for (var i=0; i < retries; i++) {
    p = p.catch(doAsync);
  }
  return p;
};

function ayncFunc3() {
  function recurse(i) {
    return doAsync().catch(function(e) {
      if (i < retries) {
        return recurse(++i);
      }
      throw e;
    });
  }
  return recurse(0);
};

ayncFunc().catch(function(e) { console.log(e); })
.then(ayncFunc2).catch(function(e) { console.log(e); })
.then(ayncFunc3).catch(function(e) { console.log(e); });
      

<div id="div"></div>
      

Run codeHide result


+8


source







All Articles