Home How to get result of all function asynchronous in sails js
Reply: 1

How to get result of all function asynchronous in sails js

Pratik Gadoya
1#
Pratik Gadoya Published in 2018-01-12 10:14:30Z

I want to execute n number of queries based on condition passed as array in request. I am able to execute all queries turn by turn but sometimes second query is executed before first query so only result of second query is displayed.

This is what I did until now.

var where_clauses = condition_array;
return new Promise(function (resolve, reject) {
    var counter = [];
    async.series([
        function (counterCB) {
            where_clauses.forEach(function (where_clause, i) {
                Model.count(where_clause, function (err, result) {
                    if (err) {
                        return counterCB(err);
                    }
                    console.log('result', result);
                    counter.push(result);
                    if ((where_clauses.length - 1) === i) {
                        return counterCB(null, counter);
                    }
                });
            });
        }
    ], function (err, result) {
        console.log('counter', counter);
        return err ? reject(err) : resolve(counter);
    });
});

Below is output of this.

Output 1:

result 26627
result 37630
counter [ 26627, 37630 ] // This is return array

Output 2:

result 37630
counter [ 37630 ] // This is return array
result 26627

Now I want that once result of all queries are stored in array than after I need to return. Can anyone help me?

arbuthnott
2#
arbuthnott Reply to 2018-01-12 13:22:24Z

The quick solution is just to change how you set up your end condition. Since your async callbacks might execute in any order, you should not conclude after the "last" callback, but after you have the number of results expected.

Try changing this:

if ((where_clauses.length - 1) === i) {
    return counterCB(null, counter);
}

to this:

if (counter.length >= where_clauses.length) {
    return counterCB(null, counter);
}

However, setting this up every time you want to wait for multiple queries to finish is difficult, and it's worth using one of the libraries to make it easier. I use Q. Then when I want to wait for multiple queries it looks like this:

var Q = require('q');

module.exports = {

    getLotsOfData: function(req, res) {
        Q.all([
            User.find({flagged: true}),
            Group.find({flagged: true}),
            someOtherCustomPromise(args)
        ]).spread(function(users, groups, otherpromiseresult) {
            // do whatever you want with all three result sets
            return res.send({
                users: users,
                groups: groups,
                otherResult: otherpromiseresult
            });
        }).fail(function(err) {
            // handle the error
        });
    },
    // etc

}

I mostly do it like this - to initiate several queries at once, then run some code once I have all the results... but Q has lots of other utility methods as well.

Hope this helps!


UPDATE

If you need a variable number of async calls, you can handle it by passing an array of promises to Q and then accessing the results using the arguments keyword in the spread callback:

Q.all(arrayOfPromises).spread(function() {
    var results = [];
    for (var i = 0; i < arguments.length; i++) {
        var oneResult = arguments[i];
        // oneResult is the result of the i'th promise in arrayOfPromises
        results[i] = oneResult;
    }
    return res.sent(results);
}).fail(function(err) {
    // handle the error
});
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.314951 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO