1

I'm new to nodejs and ES6 and trying to get my head around promises. I have a requirement to retry a dynamodb query function for specific intervals (5 seconds in this case) if the the result is not acceptable! So I have a function like this:

const retryFunc = (ddbParams, numberOfRetry) => {
return new Promise((resolve, reject) => {
  return DDBUtils.query(ddbParams).then(result => {
    //need to return a specific number of rows from the ddb table
    if(numberOfRetry > 0){
      if(result.length !== 100){
        numberOfRetry = numberOfRetry - 1
        setTimeout(() => {
          retryFunc(ddbParams, numberOfRetry)
        }, 5000)
      }
    }
    resolve(result)
  }).catch(error => {
    reject(error)
  })
})

}

When the dynamodb query returning the acceptable result (100 records) in the first call then the function working fine and returning the result to the caller. But if the function needs to be retried to satisfied the 100 condition then it is not returning the result to the caller when it gets satisfied! Can anybody help me to understand what is happening?

Nisman
  • 1,271
  • 2
  • 26
  • 56
  • There are multiple questions like this that already have answers here on stack overflow. Please use search and attempt to find some of the previous ones. – jfriend00 Sep 19 '18 at 00:48
  • Other related answers: [How to handle connect error 5 times, then create an exception](https://stackoverflow.com/questions/47859951/how-to-handle-connect-error-5-times-and-create-an-exception/47861553#47861553) and [Retry nodejs http request](https://stackoverflow.com/questions/52154317/retry-nodejs-http-request-post-put-delete/52154446#52154446) and [How can you retry after an exception in Javascript using promises](https://stackoverflow.com/questions/30471131/how-can-you-retry-after-an-exception-in-javascript-when-using-promises). – jfriend00 Sep 19 '18 at 00:55
  • More related answers: [General solution to retry a promise in Javascript](https://stackoverflow.com/questions/43568352/general-solution-to-retry-a-promise-in-javascript), [Fetch retry if request fails](https://stackoverflow.com/questions/46175660/fetch-api-retry-if-http-request-fails/46176314#46176314), [Promise retry pattern memory footprint](https://stackoverflow.com/questions/50838196/promise-retry-pattern-memory-footprint/50841345#50841345). – jfriend00 Sep 19 '18 at 00:58

1 Answers1

2

First, avoid the explicit promise construction antipattern - .query already returns a Promise, so there's no need to construct another one. Then, you inside your if(result.length !== 100){, you need to be able to chain together recursive calls of retryFunc; you can't directly return from an (asynchronous, callback-based) setTimeout, as with your current code.

One option would be to create a delay function, which returns a Promise that resolves after the desired amount of time - then, you can use return delay(5000).then(() => retryFunc(ddbParams, numberOfRetry - 1)) to return the recursive call.

const delay = ms => new Promise(res => setTimeout(res, ms));
const retryFunc = (ddbParams, numberOfRetry) => {
  return DDBUtils.query(ddbParams).then(result => {
    if(numberOfRetry > 0 && result.length !== 100) {
      return delay(5000).then(() => retryFunc(ddbParams, numberOfRetry - 1));
    }
  });
}
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320