Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 需要在forEach完成后发送响应_Node.js_Mongodb_Express_Mongoose - Fatal编程技术网

Node.js 需要在forEach完成后发送响应

Node.js 需要在forEach完成后发送响应,node.js,mongodb,express,mongoose,Node.js,Mongodb,Express,Mongoose,我正在使用NodeJS+Mongoose,我试图填充一个对象数组,然后将其发送到客户端,但我做不到,响应总是空的,因为它是在forEach结束之前发送的 router.get('/', isAuthenticated, function(req, res) { Order.find({ seller: req.session.passport.user }, function(err, orders) { //handle error var response = [];

我正在使用NodeJS+Mongoose,我试图填充一个对象数组,然后将其发送到客户端,但我做不到,响应总是空的,因为它是在forEach结束之前发送的

router.get('/', isAuthenticated, function(req, res) {
Order.find({ seller: req.session.passport.user }, function(err, orders) {
    //handle error
      var response = [];
      orders.forEach(function(doc) {
        doc.populate('customer', function(err, order) {
          //handle error
          response.push(order);
        });
      });
      res.json(response);
  });
});

有没有办法在循环完成后发送它?

一种解决方案是使用承诺

var Promise = require('bluebird');

Promise.promisifyAll(Order);

router.get('/', isAuthenticated, function(req, res) {
    Order.findAsync({ seller: req.session.passport.user })
    .then(function(orders) {
        return Promise.all(orders.map(function(doc){
            return Promise.promisify(doc.populate).bind(doc)('customer');
        }));
    }).then(function(orders){
        // You might also wanna convert them to JSON
        orders = orders.map(function(doc){ return doc.toJSON() });
        res.json(orders);
    }).catch(function(err){
        //handle error
    });
});

.promisifyAll
创建对象的所有函数的
..Async
版本,这为您节省了配置初始承诺的额外步骤。因此,我在上面的示例中使用了
Order.findAsync
,而不是
Order.findAsync
,基本上,您可以使用异步控制流管理的任何解决方案,如或承诺(有关详细信息,请参阅),但我建议您使用专门的Mongoose方法在一个MongoDB查询中填充整个数组

最简单的解决方案是用于获取已填充的文档:

Order.find({
  seller: req.session.passport.user
}).populate('customer').exec(function(err, orders) {
  //handle error
  res.json(orders);
});
但是,如果由于某种原因,您不能使用此方法,您可以调用自己来填充已获取文档的数组:

Order.populate(orders, [{
  path: 'customer'
}], function(err, populated) {
  // ...
});

就这样<代码>查询#填充工作起来很有魅力。非常感谢你!我不知道承诺是什么,因为我是个彻头彻尾的傻瓜。我会调查他们和蓝鸟。太谢谢你了!