简体   繁体   中英

Node.js - Building JSON asynchronously with multiple queries

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM