1

I have a array of ids:

var ids = ['53asd3','53asd2','53asd5'];

Each id has a corresponding document in the mongodb. I want to generate a object by populating data from each of them and save in some other document. Like this:

{
    person: {   /* data from some collection populated with first id */},
    company : { /* data from some collection populated with first id */},
    employee : {/* data from some collection populated with first id */}
} 

WHAT I DID

var document = {}
models.persons.find({_id:'53asd3'},function(err,data){
    if(!err) {
        document['persons']=data;
        models.company.find({_id:'53asd2'},function(err,data){
            if(!err) {
                document['company']=data;
                models.employee.find({_id:'53asd2'},function(err,data){
                    if(!err) {
                        document['employee']=data;
                        document.save(function(err){ });
                    }
                });
            }
        });
    }
});

So I just use nested calls using callbacks and somewhat make it synchronous. Is there a chance where I can execute all these three find queries in parallel and then execute the save command? I actually want to leverage the async nature of node.js. Any suggestions?

4
  • You might want to look into Promises Commented Jun 2, 2014 at 14:13
  • 1
    Look at async.parallel. Commented Jun 2, 2014 at 14:16
  • Well i know the promises might work here but wanted to use something without any external library. So is there a way i can do it with node.js itself? My code is essentially synchronous now! However i really liked async.parallel! Amazing module :) Commented Jun 2, 2014 at 14:18
  • question aside...to reduce nesting, especial with a callback-centric platform like node.js, you should change if(!err) {...} to if(err) return;. Assuming of course you want to ignore any errors. Sorry, couldn't help myself :) Commented Jun 7, 2014 at 4:20

1 Answer 1

1

You could build something like async.parallel yourself if you don't want to include an external library. Here's what a simple parallel function might look like. It could be a nice exercise to implement the other functions in the async library.

var parallel = function () {
    var functs = arguments[0];
    var callback = arguments[1];

    // Since we're dealing with a sparse array when we insert the results,
    // we cannot trust the `length` property of the results.
    // Instead we count the results separately
    var numResults = 0;
    var results = [];
    var getCallback = function (i) {
        return function (err, res) {
            if (err) {
                callback(err)
            }
            else {
                results[i] = res;
                numResults += 1;

                if (numResults === functs.length) {
                    callback(null, results);
                }
            }
        }
    }

    functs.forEach(function (fn, i) {
        fn(getCallback(i));
    });
};


var getTest = function (timeout) {
    return function (callback) {
        setTimeout(function () {
            callback(null, timeout);
        }, timeout);
    }
};

parallel([getTest(99), getTest(1000), getTest(199)], console.log.bind(console));
>> null [99, 1000, 199]

Then in your case you can do something like

var findItem = function (collection, id) {
    return function (callback) {
        collection.find({
            _id: id
        }, callback);
    };
};

parallel([
    findItem(models.persons, '53asd3'),
    findItem(models.company, '53asd2'),
    findItem(models.employee, '53dsa2')
], function (err, results) {
    document.persons = results[0];
    document.company = results[1];
    document.employee = results[2];
    document.save(function (err) {
        // and so on
    });
});
Sign up to request clarification or add additional context in comments.

Comments

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.