Chaining nested asynchronous finds with Node.js monk and MongoDB

和自甴很熟 提交于 2019-12-25 16:08:45

问题


Using Node.js monk and MongoDB, I want to mimic a table join:

  1. Do a find on collection A
  2. For each result X, do a find in collection B, and update X
  3. Return updated list of results

The asynchronous nature of database commands in monk is giving me trouble. This is my initial code. It doesn't work because the second call to find returns a promise immediately, and the results in xs are sent in the response before they can be updated.

var db = require('monk')('localhost/mydb');
db.get('collection').find({}, function(e,xs) {
  xs.forEach(function(x){
    coll_b.find({a_id:x._id}, function(e,bs) {
      a['bs'] = bs;
    });
  });
  res.json({'results':as});
});

I feel like I should use promise chaining here, but I cannot figure out how to do it. Any help would be greatly appreciated.


回答1:


I think I solved it in this way, inspired by this answer:

var db = require('monk')('localhost/mydb');

// Initial find
db.get('collection').find({}, function(e,xs) {

  // Get inner finds as a list of functions which return promises
  var tasks = xs.map(function(x){
    return function() {
      return coll_b.find({a_id:x._id}, function(e,bs) {
        a['bs'] = bs;
      });
    }
  });

  // Chain tasks together
  var p = tasks[0](); // start the first one
  for(var i = 1; i < tasks.length; i++) p = p.then(tasks[i]);

  // After all tasks are done, output results
  p.then(function(_x){
    res.json({'results':xs});
  });

});

I still feel like this code could be minimised by using chain(), but at least this works as expected.

Note: I realise that performing a second find for each result is not necessarily efficient, but that's not my concern here.



来源:https://stackoverflow.com/questions/31400386/chaining-nested-asynchronous-finds-with-node-js-monk-and-mongodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!