blipblop
blipblop

Reputation: 387

Nodejs for loop callback issues

I wrote this function that should run this for loop and then the callback at the end but it keeps running the callback before it finishes the loop. The only solutions I've read said using a callback would fix this issue but it doesn't seem to be making much of a difference.

function run(callback){
  for(var i = 0; i < urls.length; i++){
    request(url, function(error, resp, body){
      //uses cheerio to iterate through some elements on the page
      //then saves to an object for a future response  
    });
    callback();
  }
}

Upvotes: 0

Views: 958

Answers (3)

eljefedelrodeodeljefe
eljefedelrodeodeljefe

Reputation: 6791

First of all your code example is missing some brackets. request is likely an asynchronous library. So at it's function call it's registering with the event loop and returns immediately. Meaning you actually call the callback immediately, probably without request having finished. So synchronously looping with async functions won't work.

Either use something like Promises, Continuation Passing, or register a variable, which tracks whether all calls have returned already.

Upvotes: 0

Santiago Hern&#225;ndez
Santiago Hern&#225;ndez

Reputation: 5636

I would add a variable called totaltasks and another one called tasksfinished. Then when a request is finished increment tasksfinished, and call your callback whenever tasksfinished equals totaltasks:

function run(callback){
  var totaltasks = urls.length;
  var tasksfinished = 0;

  // helper function
  var check = function() {
    if(totaltasks == tasksfinished) {
       callback();
    }
  }

  for(var i = 0; i < totaltasks; i++){
    try {
      request(url, function(error, resp, body) { 

        tasksfinished++;
        check();
     });
    } catch(e) {
      tasksfinished++;
      check();
    }
  }
};

Upvotes: 1

Adam
Adam

Reputation: 3518

You need to move your callback function inside of the request callback:

function run(callback){
  for(var i = 0; i < urls.length; i++){
     request(url, function(error, resp, body){    
        //uses cheerio to iterate through some elements on the page
        //then saves to an object for a future response  
         callback();
     });

}

Upvotes: 0

Related Questions