Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call promise function recursively

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?

like image 325
benjaminjosephw Avatar asked Mar 13 '23 07:03

benjaminjosephw


2 Answers

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
    }
  });
}
like image 21
Bergi Avatar answered Mar 23 '23 19:03

Bergi


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){
like image 179
Matt Avatar answered Mar 23 '23 21:03

Matt