Search code examples
javascriptnode.jspromisees6-promise

Issue with Promise not getting resolved with maximum retries attempt


I am struggling for past couple of days with Promise and a beginner. I have to call an external API and check if response is there or not. If null then call api again with maximum retry attempts, that is configurable. I tried the following, but not sure what I am missing here. Here is a sample what I did.

If data is available then show data is available. If not then retry for some time and if reaches zero then resolve with data not availabe in API. If data is available after some retry (for eg: 2nd time) then stop and show response.

function callExternalAPI(retry, interval) {
 try {
    return new promise((resolve, reject) => {
        if(retry <=0 ) {
            return resolve("Data not available in API"); // This is not working, request is hanged.
        }
        return myapiCall().then((response) => {
           if(!response) {
              // If empty then retry calling api again
              return setTimeOut(async () => {
                 await callExternalAPI(retry - 1, interval)
              }, interval);
           }
           return resolve(response);
        })
    })
}
   } catch((error) => {
       reject(error);
    })



callExternalAPI(3, 1000).then((rsp) => {
   console.log({response: "data available"});
}).catch((error) => {
  throw error;
})

Any help would be really appreciated as I am still on the learning phase.

Thanks in Advance


Solution

  • One way to do this is to wrap the "waiting" between tries into a separate async method and await this method.

    Then, simply recur callExternalApi if no successful result has been returned from myapiCall as long as the retry-count has not reached 0. Note that in my example I'm throwing an error if we've reached the max count (you can handle this differently of course like returning undefined/null):

    async function wait(timeInMs) {
      console.log('Waiting ...');
      return new Promise((resolve => setTimeout(() => resolve(), timeInMs)));
    }
    
    
    async function callExternalApi(numberOfTries, timeout) {
      if (numberOfTries <= 0) {
        return "Data not available in API";
      }
    
      const result = await myapiCall();
    
      if (result) {
        return result;
      }
    
      await wait(timeout); // wait for the defined timeout before recurring
    
      return callExternalApi(numberOfTries - 1, timeout);
    }
    
    (async () => {
       try {
         const result = await callExternalApi(3, 1000);
         console.log(result);
       } catch(err) {
         console.log(err);
       }
    })();