2013-05-21 101 views
1

如何在一行中写入多个查询?nodejs中的多个异步mongo请求

Space.findOne({ _id: id }, function(err, space) { 
    User.findOne({ user_id: userid }, function(err, user) { 
     res.json({ space: space, user: user}); 
    }); 
}); 

不好看更多的要求和逻辑

它是如何正确地完成?

我听说了诺言,但我不知道。

感谢

+0

你想让这些函数异步执行或者像你的示例代码一样执行吗? –

回答

7

当我也有过类似的问题,我已经使用了async库。

async.parallel([ 
    function(callback){ 
     Space.findOne({ _id: id }, callback); 
    }, 
    function(callback){ 
     User.findOne({ user_id: userid },callback); 
    } 
], 
function(err, results){ 
    res.json({space:results[0],user:results[1]}); 
}); 

如果您想要顺序执行,也可以使用async.series。

+0

请注意,使用'.bind'可以缩短代码的长度,但为了清晰起见,我避免了这种情况。 –

+0

注意2015年,两年后 - 我会承诺做到这一点,他们是这个问题更优雅的解决方案。如果有人在意留下评论,我会用承诺添加答案。 –

3

@本杰明的方法是正确的。 Mongoose还提供了populate方法,该方法通过它们的id获取彼此相关的多个对象。这也同时发生,并且是多个查询的特例。有关更多示例,请参见http://mongoosejs.com/docs/populate.html

0

如果您使用支持Promise的Node.js 4+,则可以将查询包装在承诺中。

queryPromise = function(findQueryCursor) { 
    return new Promise(function(resolve, reject) { 
    findQueryCursor.toArray(function(err, data) { 
     resolve(data); 
    }); 
    }); 
}; 

然后,创建包括查询的承诺的数组:

promiseAr = []; 
promiseAr.push(
    queryPromise(
    db.collection('dbname').find(query1) 
) 
); 
promiseAr.push(
    queryPromise(
    db.collection('dbname').find(query2) 
) 
); 

然后调用

Promise.all(promiseAr) 
.then(function(dataArray) { 
    // results of query1 in dataArray[0] 
    // results of query2 in dataArray[1] 
}) 
.catch(function(err) { 
    // catch errors 
}); 

的查询将被并行地发送到MongoDB的,而 “然后”函数将在所有查询完成后调用。

您必须这样做的原因是因为.find()函数返回一个游标,然后您必须调用.toArray()来检索数据。 .toArray()本身是异步的,所以如果你想使用Promise.all,你必须把它包装在Promise中。