Ahmed H. Saab
Ahmed H. Saab

Reputation: 413

How to wait for N number of queries to finish before calling the callback function with Nodejs

I am trying to create a function that quires the database and returns a list of objects and for each object i need to query the database and return the result of all the queries.

How to wait for all the queries to finish, or should i do them in a synchronous way? If so How ? Shouldn't i be exploiting the fact that they are all select queries and doesn't depend on each other so run them in parallel to optimize time? Is that a bad design ? or maybe i should use stored procedures for this?

getTopActiveUsers:function(callback) {
    pool.connect(function (err, client, done) {
        if (err)
            callback(null, err);
        else {
            User.finAll(client,function(users) {
                for(var i=0;i<users.length;i++) {
                    Application.findByUser(users[i].id,function(applications) {
                        // here i have the applications for user i
                    })
                }
                // need to call the callback function when all queries finishes
            })
        }
    });
}

Upvotes: 0

Views: 136

Answers (2)

jfriend00
jfriend00

Reputation: 707366

Since these can be all run in parallel, the simplest way with the code you already have is to just keep a counter:

getTopActiveUsers:function(callback) {
    pool.connect(function (err, client, done) {
        if (err)
            callback(null, err);
        else {
            User.findAll(client,function(users) {
                var doneCnt = 0;
                for(var i=0;i<users.length;i++) {
                    Application.findByUser(users[i].id,function(applications) {
                        // here i have the applications for user i
                        ++doneCnt;
                        if (doneCnt === users.length) {
                            callback(null, someResult);
                        }
                    })
                }
            })
        }
    });
}

A more advanced (and more flexible) mechanism would be to learn and use a promise-based interface to your database and then you can use Promise.all() to track when multiple async operations are done.

Upvotes: 1

F. Kauder
F. Kauder

Reputation: 889

async library is for you. The parallel method execute all your requests in parallel, and wait they all finished.

getTopActiveUsers : function(callback) {
pool.connect(function(err, client, done) {
    if (err) {
        callback(null, err);
    } else {
        User.finAll(client, function(users) {
            var requests = [];

            for (var i = 0; i < users.length; i++) {
                requests.push(function(asyncCallback) {
                    Application.findByUser(users[i].id, function(applications) {
                        // here i have the applications for user i
                        asyncCallback();
                    });
                });

            }

            async.parallel(requests, function(err) {
                // Requests are finished here
            });
        })
    }
});
}

Documentation : http://caolan.github.io/async/

Upvotes: 3

Related Questions