javascript - Preserving Execution order in nested for loop and callbacks in NodeJS MongoDB -


scenario: there users , users has many posts. particular group of users, need fetch 10 recent posts per user , send them in response. here have come with: 

users array having user info.

var allposts = [];  for(var i=0; i<users.length; i++){     (function(i){                                               //level-1          db.collection('posts', function(err, postcollection){             (function(i){                                       //level-2                 postcollection.find({"user_id": users[i]['user_id']}).sort({"created": -1}).limit(10).toarray(function(err, post) {                     (function(i){                               //level-3                         for(var j =0; j< post.length; j++){                             (function(j){                                 post[j]['created'] = objectid(post[j]['_id'].tostring()).gettimestamp();                                 allposts.push(post[j]);                                 if(j === post.length-1){                                     res.send(allposts);                                 }                             })(j);                         }                         })(i);                 });             })(i);         });         })(i);                         } 

now, execution order preserved level-2, when enters level-3, things go wrong: have 2 users in array , 1 user has 3 posts , has 10 posts, response 3 posts , 13 posts. think because of mongodb. taking care of execution order using invoked function expression(iife), not seem work here. appreciated. thanks

first of should beautify code. using anonymous functions inside loops inside callbacks of other loops not easy maintain or read.

the problem code in last loop ( j loop ) j == users.length - 1 before queries others users finished response sent number of post queries finished until moment.

one other big mistake made request post collection inside loop. that's wrong! should cache both database , collection.

try code:

var allposts = []; var post_collection = null;  var get_user = function(i, callback) {     post_collection         .find({"user_id": users[i]['user_id']})         .sort({"created": -1})         .limit(10)         .toarray(function(err, post) {              // when error             // call callback function if there 1             if(err) {                 callback();                 return;             }              for(var j=0; j<post.length; ++j) {                 post[j]['created'] = objectid(post[j]['_id'].tostring()).gettimestamp();                 allposts.push(post[j]);             }              callback();         }); };  var fetch_users = function() {     var count = users.length;      for(var i=0; i<users.length; ++i) {         get_user(i, function() {             // each time query 1 user done decrement counter             count--;              // when counter 0 know queries have been done             if(count === 0) {                 res.send(allposts);             }         });     };     };  // collection, check errors , cache it! db.collection('posts', function(err, postcollection) {      // check database errors     if(err) {         console.log(err);         return;     }      post_collection = postcollection;     fetch_users(); }); 

you should know code not tested. might have missed semicolon or braces should figure out easily.


Comments

Popular posts from this blog

how to proxy from https to http with lighttpd -

android - Automated my builds -

python - Flask migration error -