nested loops asynchronously in Node.js, next loop must start only after one gets completed

12,162

Solution 1

In node.js you need to use asynchronous way. Your code should look something like:

var processUsesrs = function(callback) {
    getAllUsers(function(err, users) {
        async.forEach(users, function(user, callback) {
            getContactsOfUser(users.userId, function(err, contacts) {
                async.forEach(contacts, function(contact, callback) {
                    getPhonesOfContacts(contacts.contactId, function(err, phones) {
                        contact.phones = phones;
                        callback();
                    });
                }, function(err) {
                    // All contacts are processed
                    user.contacts = contacts;
                    callback();
                });
            });
        }, function(err) {
            // All users are processed
            // Here the finished result
            callback(undefined, users);
        });
    });
};

processUsers(function(err, users) {
    // users here
});

Solution 2

You could try this method without using async:

function getAllUserContacts(users, callback){
   var index = 0;
   var results = [];
   var getUserContacts = function(){
      getContactsOfUser(users[index].userId, function(contacts){
        var index2 = 0;
        var getContactsPhones = function(){
          getPhonesOfContacts(contacts[index2].contactId, function(phones){
            contacts[index2].phones = phones;
            if(index2 === (contacts.length - 1)){
              users[index].contacts = contacts;
              if(index === (users.length - 1)){
                callback(users)
              } else {
                index++;
                getUserContacts();
              }
            }else{
              index2++;
              getContactsPhones();
            }
          });
         }
         getContactsPhones();
      });
   }
   getUserContacts();
}

//calling the function
getAllUsers(function(users){
   getAllUsersWithTheirContacts(users, function(usersWithContacts){
      console.log(usersWithContacts);
   })
})
Share:
12,162
Maulik Vora
Author by

Maulik Vora

A passionate Software Engineer API Integration Expert and consultant Contact for : MySql, PHP5, HTML, HTML5 , Jquery, Jquery-Mobile, Codeigniter, MongoDB Android / iOS Mobile Development Help in defining Database architecture, Defining Project Architecture, software design and testing, data scraping. For coding efficient/custom scripts/cronjobs Smart guidance in optimizing your existing algorithms or logic.

Updated on June 20, 2022

Comments

  • Maulik Vora
    Maulik Vora almost 2 years

    Check below algorithm...

    users = getAllUsers();
    for(i=0;i<users.length;i++)
    {
        contacts = getContactsOfUser(users[i].userId);
        contactslength = contacts.length;
        for(j=o;j<contactsLength;j++)
        {
             phones = getPhonesOfContacts(contacts[j].contactId);
             contacts[j].phones = phones;
        }
        users[i].contacts = contacts;
    }
    
    return users;
    

    I want to develop such same logic using node.js.

    I have tried using async with foreach and concat and foreachseries functions. But all fail in the second level.

    While pointer is getting contacts of one user, a value of i increases and the process is getting started for next users. It is not waiting for the process of getting contacts & phones to complete for one user. and only after that starting the next user. I want to achieve this.

    Actually, I want to get the users to object with proper

    Means all the sequences are getting ruined, can anyone give me general idea how can I achieve such a series process. I am open to change my algorithm also.