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);
}
}
});
};
source to share
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>
source to share