Reputation: 3011
I have started coding in Node.js last week. I have wrote code to generate JSON querying multiple tables and not sure if this is correct way of coding asynchronously
build_actor(post, function(actor){
build_post_object(post, function(post_object){
build_post_attachments(post, function(attachments){
build_post_comments(post, function(comments){
var post_obj = {};
post_obj.actor = actor;
post_obj.object = post_object;
post_obj.attachments = attachments;
post_obj.comments = comments;
console.log(JSON.stringify(post_obj)); // generates JSON
});
});
});
});
function build_actor(post, callback){
//query
callback(actor);
}
function build_post_object(post, callback){
//query
callback(post_object);
}
function build_post_attachments(post, callback){
//query
callback(attachments);
}
function build_post_comments(post, callback){
//query
callback(comments);
}
Kindly let me know if there is a better way for writing multiple queries and building a JSON.
Upvotes: 1
Views: 557
Reputation: 14953
I see that you already got an answer, but I thought I could see if it is possible to make a really elegant solution using async (should be less code and/or easier to read than the original solution), just as an exercise. And it is:
async.series({
actor: async.apply(build_actor, post),
post_object: async.apply(build_post_object, post),
attachments: async.apply(build_post_attachments, post),
comments: async.apply(build_post_comments, post)
},
function (err, result) {
console.log(JSON.stringify(result));
});
The build_*-functions must also callback null (or an error) as the first argument. This is generally a good idea since most of node.js' apis and modules work that way. For example:
function build_actor(post, callback) {
// Query
callback(null, actor);
}
Note that I haven't actually tested it, but it should work.
So the magic here is that async.series
can compose the result as an object, where the keys for the result are the same as you assign the functions. Thus you don't need do assing values to an object but can convert it straight away. async.apply
is just a more simple way of calling a function with an already available argument. The plain way would be:
function (callback) {
build_actor(post, callback);
}
Another way would be to rewrite your fetching functions like this:
function build_actor(post){
return function (callback) {
//query
callback(null, actor);
};
}
And use them like this:
async.series({ actor: build_actor(post) }, ...);
which would be even cleaner. Also note that if you can run the queries at the same time, async.parallel
would work just as well.
Upvotes: 1