需要在forEach完成后发送响应

时间:2015-06-14 18:03:24

标签: node.js mongodb express mongoose

我正在使用NodeJS + Mongoose,我正在尝试填充一个对象数组然后将其发送到客户端,但我不能这样做,响应始终为空,因为它是在每个结束之前发送的。

p

循环结束后有没有办法发送它?

2 个答案:

答案 0 :(得分:5)

基本上,您可以使用任何解决方案进行异步控制流管理,如async或promises(有关详细信息,请参阅laggingreflex's answer),但我建议您使用专门的Mongoose方法填充整个数组一个MongoDB查询。

最直接的解决方案是使用Query#populate method来获取已填充的文档:

Order.find({
  seller: req.session.passport.user
}).populate('customer').exec(function(err, orders) {
  //handle error
  res.json(orders);
});

但是,如果出于某种原因,您无法使用此方法,则可以自己调用Model.populate method来填充已经提取的文档数组:

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

答案 1 :(得分:3)

一种解决方案是使用Promises。

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
    });
});

BlueBird' .promisifyAll为对象的所有功能创建…Async版本,这为您在配置初始承诺时节省了额外的一步。因此,我在上面的示例

中使用Order.find而不是Order.findAsync