0

I've been pointed towards using the async module, but I'm not quite sure how to use waterfall to solve my problem.

My original code had problems with asynchronicity.

        var Image    = require('./models/image');
        var User     = require('./models/user');

        var query = Image.find({});

        query.limit(10);
        query.sort('-date')

        query.exec(function (err, collected) {
          if (err) return console.error(err);
            var i = 0;
            var authors = [];

            while (i < 8) {
                var search = User.find({'twitter.id' : collected[i].author});


                search.exec(function (err, user){
                    if (err) return console.error(err);

                    var result = (user[0].twitter.username);
                    authors.push(result);
                });

                i = i + 1;
            }
        }

        console.log(authors);

I want the authors array to hold all the found usernames. However when that last console.log() call returns '[]'

1 Answer 1

1

So, you want to wait for all of the searches to complete first. You should put all your async calls into an array, and then use an async library to chain them together (waterfall) or execute simultaneously (parallel). Parallel tends to execute "faster":

var searches = [];
while (i < 8) {
    var search = User.find({'twitter.id' : collected[i].author});
    searches.push(function(cb) {
        search.exec(function (err, user){
            if (err) cb(err, null);
            else cb(null, user[0].twitter.username);
        });
    });
    i++;
}
async.parallel(searches, function( err, authors ) {
    if ( err ) return console.error( err );
    console.log(authors);
    // Authors only defined here.
    //  TODO: More code
});
// Authors not defined here.
Sign up to request clarification or add additional context in comments.

5 Comments

Ooh okay, fantastic. What's cb within the exec function?
It's the callback function, letting the async library know that it is completed. You can read a bit more here: github.com/caolan/async#parallel
I don't know if I've made a slight error. My code throws the error that 'cb isn't defined' but I'm assuming it's not something I define and is instead already defined within the async module (assuming it has specific behaviour, with an error and a results array).
Sorry, typo on my part. Defined as function parameter.
A weird glitch with this code is that I get an array full of only one username. Say it is parsing a dataset that definitely includes two different authors. I only get one. Very very odd.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.