nodejs中的多个异步mongo请求
Posted
技术标签:
【中文标题】nodejs中的多个异步mongo请求【英文标题】:multiple async mongo request in nodejs 【发布时间】:2013-05-15 16:28:03 【问题描述】:如何连续编写多个查询?
喜欢一个
Space.findOne( _id: id , function(err, space)
User.findOne( user_id: userid , function(err, user)
res.json( space: space, user: user);
);
);
更多的请求和逻辑看起来不太好
如何正确完成?
我听说了一些关于承诺的事情,但我不知道。
谢谢
【问题讨论】:
您希望函数彼此异步执行还是像示例代码中那样一起执行? 【参考方案1】:如果您使用的是支持 Promises 的 Node.js 4+,则可以将查询包装在 Promise 中。
queryPromise = function(findQueryCursor)
return new Promise(function(resolve, reject)
findQueryCursor.toArray(function(err, data)
resolve(data);
);
);
;
然后,创建一个由查询组成的 Promises 数组:
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,所有查询完成后将调用“.then”函数。
你必须这样做的原因是因为 .find() 函数返回一个游标,然后你必须调用 .toArray() 来检索数据。 .toArray() 本身是异步的,所以如果你想使用 Promise.all,你必须将它包装在 Promise 中。
【讨论】:
很棒的代码。花了半个小时寻找答案,这是唯一更新的。这应该被投票给顶部。谢谢! 我应该为所有承诺使用一个连接实例还是为每个承诺使用一个实例?当我在 Promise 中创建连接实例时,我收到错误响应“在调用 MongoClient.prototype.db 之前必须连接 MongoClient” 我不再和 Mongo 打交道了。我的猜测是,在发送查询之前,您需要先等待连接返回。将连接包装在 Promise 中,然后执行 connectPromise().then(result) ... 然后发送您的查询。如果您使用的是 ES6,则可以使用一些人认为更直接的 async / await 语法。它与 Promise 相同,语法更简洁。【参考方案2】:@Benjamin 的方法是正确的。 Mongoose 还提供了populate
方法,该方法可以获取多个通过 id 相互关联的对象。这也是并行发生的,是多个查询的特例。有关更多示例,请参阅http://mongoosejs.com/docs/populate.html。
【讨论】:
【参考方案3】:当我遇到类似问题时,我使用了 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。
【讨论】:
注意,使用.bind
可以缩短这段代码,但为了清楚起见,我会避免这样做。
注意 2015 年,两年后 - 我会用承诺来做这件事,它们是解决这个问题的更优雅的解决方案。如果有人关心发表评论,我会用承诺添加答案。以上是关于nodejs中的多个异步mongo请求的主要内容,如果未能解决你的问题,请参考以下文章
使用异步和请求包(NodeJS / Express)进行多个 API 调用