问题
I want my function to execute X(=3) times until success.
In my situation I'm running kinesis.putRecord
(from AWS API), and if it fails - I want to run it again until it succeeds, but not more than 3 tries.
I'm new to NodeJS, and the code I wrote smells bad.
const putRecordsPromise = function(params){
return new Promise((resolve, reject) => {
kinesis.putRecord(params, function (err, data) {
resolve(err)
});
})
}
async function waterfall(params){
try{
let triesCounter = 0;
while(triesCounter < 2){
console.log(`try #${triesCounter}`)
let recordsAnswer = await putRecordsPromise(params)
if(!recordsAnswer){
console.log("success")
break;
}
triesCounter += 1;
}
// continue ...
} catch(err){
console.error(err)
}
}
waterfall(params)
I promise the err result. Afterwards, If the err is empty, then all good. otherwise, continue running the same command.
I'm sure there is a smarter way to do this. Any help would be appreciated.
回答1:
I think, all the Aws functions can return a Promise out of the box, then you can just put the call into try/catch
:
let triesCounter = 0;
while(triesCounter < 2){
console.log(`try #${triesCounter}`)
try {
await kinesis.putRecord(params).promise();
break; // 'return' would work here as well
} catch (err) {
console.log(err);
}
triesCounter ++;
}
回答2:
Make a little module, say try-and-try-again.js
:
exports = module.exports = tryAndTryAgain;
function tryUntilSuccess( maxTries, thisContext , fn, ...argv) {
let success = false;
for (let i = i ; i < maxTries && !success ; ++i ) {
let rc = fn.apply(thisContext, args);
success = rc == 0 ? true : false;
}
return success;
}
Then you can use it anywhere:
const tryAndTryAgain = require('./try-and-try-again');
function somethingThatMightNeedARetry() { ... }
const succeeded = tryAndTryAgain( 3 , null, somethingThatMightNeedARetry, 'arg-1', 'arg-2', 'arg-3' );
回答3:
In functional style:
...
await tryUntilSucces(() => kinesis.putRecord(params).promise());
...
async function tryUntilSucces(promiseFn, maxTries=3) {
try {
return await promiseFn();
} catch (e) {
if (maxTries > 0) {
return tryUntilSucces(promiseFn, maxTries - 1);
}
throw e;
}
}
来源:https://stackoverflow.com/questions/55031780/nodejs-retry-function-if-failed-x-times