5

I am trying to call an asynchronous function recursively using javascript promises but haven't found a pattern that works.

This is what I imagine would work:

var doAsyncThing = function(lastId){
  new Promise(function(resolve, reject){
    // async request with lastId
    return resolve(response)
  }
}

var recursivelyDoAsyncThing = function(lastId){
  doAsyncThing(lastId).then(function(response){
    return new Promise(function(resolve, reject){
      //do something with response
      if(response.hasMore){
        //get newlastId
        return resolve(recursivelyDoAsyncThing(newLastId));
      }else{
        resolve();
      }
    });
  });
}

recursivelyDoAsyncThing().then( function(){
  console.log('done');
});

Why doesn't this work? What have I misunderstood?

Is there a better pattern to solve this problem?

benjaminjosephw
  • 4,369
  • 3
  • 21
  • 40

3 Answers3

3

recursivelyDoAsyncThing needs to return a Promise in order to continue the chain. In your case, all you need to do is have doAsyncThing return its Promise:

var doAsyncThing = function(lastId){
  // Notice the return here:
  return new Promise(function(resolve, reject){

Then add return to your doAsyncThing call like so:

var recursivelyDoAsyncThing = function(lastId){
  // Notice the return here:
  return doAsyncThing(lastId).then(function(response){
Matt
  • 43,482
  • 6
  • 101
  • 102
2

You're missing a return in the recursivelyDoAsyncThing function. Also you should avoid the Promise constructor antipattern:

function recursivelyDoAsyncThing(lastId) {
  return doAsyncThing(lastId).then(function(response) {
//^^^^^^
    //do something with response
    if (response.hasMore) {
      //get newlastId
      return recursivelyDoAsyncThing(newLastId);
    } else {
      return; // undefined? Always return a useful value
    }
  });
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
2

I have a simple example of recursive promise. The example is based on calculation factorial of number.

let code = (function(){
 let getFactorial = n =>{
  return new Promise((resolve,reject)=>{
   if(n<=1){
    resolve(1);
   }
   resolve(
    getFactorial(n-1).then(fact => {
     return fact * n;
    })
   )
  });
 }
 return {
  factorial: function(number){
   getFactorial(number).then(
    response => console.log(response)
   )
  }
 }
})();
code.factorial(5);
code.factorial(6);
code.factorial(7);
Mayur Shedage
  • 1,027
  • 2
  • 11
  • 19