FranXh
FranXh

Reputation: 4771

Node.js: Callback function at the end of each iteration in a for loop

In Node.js I have a function that goes through an entire list of elements and does some database calls as shown below:

 for(var j=0; j<elements.length; j++)
 {
   //do some database calls
 }

After each loop finishes (meaning when the database calls terminate), I would like to "console.log("Loop terminated");". In the code below I have shown my attempt to solve this:

 for(var j=0; j<elements.length; j++)
 {
   (function() 
     {
      //do some database calls

     })(function(){
        console.log("Loop terminated");
       });
 }

I use an anonymous function in place, and I am trying to callback a function that will print "console.log("Loop terminated")". When I execute this code, the console.log never prints anything. I am pretty new to Node.js and I do not understand callbacks that well. Can someone explain to me why my callback is not working and how can I fix it?

Upvotes: 1

Views: 5378

Answers (1)

Andrey Sidorov
Andrey Sidorov

Reputation: 25466

If you intend to make database calls in parallel:

 numCompletedCalls = 0
 for(var j=0; j<elements.length; j++)
 {
    callDatabase(function(results) {
       numCompletedCalls++;
       if (numCompletedCalls == elements.length)
          console.log("Done all calls!");

    });
 }

if you are going to save all results you can push to allResults array and check it's length instead of incrementing counter.

If you want to have sequential for loop, you need to have recursion-like pattern (note that it's not actually recursion)

 function iterateElements(elements, index, callback) 
 {
    if (index == elements.length)
       return callback();
    // do database call with element
    var ele = elements[index];
    callDatabase(function(results) {
       iterateElements(elements, index+1, callback);
    });
 }
 iterateElements(elements, 0, function() {
    console.log("Done all calls!");
 });

most people tend to use async library, but I strongly recommend to try all async patterns manually at least once

Upvotes: 6

Related Questions