如何从find方法返回Mongoose结果?

我可以find任何与mongoose结果折页的东西说这样做:

users.find({}, function(err, docs){ res.render('profile/profile', { users: docs }); }); 

我怎么能返回查询的结果,更像这样?

 var a_users = users.find({}); //non-working example 

这样我可以得到多个结果发布在网页上?

喜欢:

 /* non working example */ var a_users = users.find({}); var a_articles = articles.find({}); res.render('profile/profile', { users: a_users , articles: a_articles }); 

可以这样做吗?

你正试图强制一个同步范例。 只是没有工作。 node.js是单线程的,大部分 – 当io完成时,执行上下文被取消。 信令通过callback进行pipe理。 这意味着你要么嵌套callback函数,命名函数或stream控制库来使事情更好看。

https://github.com/caolan/async#parallel

 async.parallel([ function(cb){ users.find({}, cb); }, function(cb){ articles.find({}, cb); } ], function(results){ // results contains both users and articles }); 

我会在这里扮演死灵法师,因为我还看到另一个更好的办法。

使用精彩诺言库Bluebird及其promisifyAll()方法:

 var Promise = require('bluebird'); var mongoose = require('mongoose'); Promise.promisifyAll(mongoose); // key part - promisification var users, articles; // load mongoose models "users" and "articles" here Promise.props({ users: users.find().execAsync(), articles: articles.find().execAsync() }) .then(function(results) { res.render('profile/profile', results); }) .catch(function(err) { res.send(500); // oops - we're even handling errors! }); 

关键部分如下:

 Promise.promisifyAll(mongoose); 

使所有的mongoose(及其模型)方法作为函数返回promise,使用Async后缀( .exec()变成.execAsync()等等)。 在Node.JS世界中, .promisifyAll()方法几乎是通用的 – 您可以在提供asynchronous函数的任何东西上使用它,以callback作为其最后一个参数。

 Promise.props({ users: users.find().execAsync(), articles: articles.find().execAsync() }) 

.props()蓝鸟方法接受带有promise的对象作为它的属性,并返回在两个数据库查询(这里是promise)都返回结果时得到解决的集体promise。 解决的值是我们在最终函数中的results对象:

  • results.users – 通过mongoose在数据库中find的用户
  • results.articles – 通过mongoose(d'uh)在数据库中find的文章

正如你所看到的,我们甚至没有接近缩进callback地狱。 两个数据库查询都是并行执行的 – 不需要其中一个等待另一个。 代码简短易读 – 实际上在问题本身中张贴的“非工作示例”的实际长度和复杂性(或者说缺乏)是相当的。

承诺是很酷的。 使用它们。

简单的方法:

 var userModel = mongoose.model('users'); var articleModel = mongoose.model('articles'); userModel.find({}, function (err, db_users) { if(err) {/*error!!!*/} articleModel.find({}, function (err, db_articles) { if(err) {/*error!!!*/} res.render('profile/profile', { users: db_users, articles: db_articles }); }); }); 

实际上,每个function在Node.js中都是asynchronous的。 mongoose的发现也是如此。 如果你想连续调用它,你应该使用像Slide库这样的东西。

但在你的情况下,我认为最简单的方法是嵌套callback(这允许选定以前的用户feitation的文章),或完全平行asynchronous库的帮助(请参阅stream量控制/asynchronous好东西 )。

我有一个function,我用了很多作为返回到节点function。

 function freturn (value, callback){ if(callback){ return callback(value); } return value; }; 

然后我有一个可选的callback参数在所有的签名。

我正在处理一个非常类似的事情,但使用来自客户端的socket.io和数据库访问。 我的发现是在数据库有机会获取数据之前将我的数据库的内容返回给客户端…所以为了什么是值得的,我将在这里分享我的发现:

我的function检索数据库:

//读板 – 完整的数据库

 var readBoards = function() { var callback = function() { return function(error, data) { if(error) { console.log("Error: " + error); } console.log("Boards from Server (fct): " + data); } }; return boards.find({}, callback()); }; 

我的套接字事件侦听器:

 socket.on('getBoards', function() { var query = dbConnection.readBoards(); var promise = query.exec(); promise.addBack(function (err, boards) { if(err) console.log("Error: " + err); socket.emit('onGetBoards', boards); }); }); 

所以为了解决这个问题,我们使用mongoose给予我们的承诺,然后一旦我们从数据库中接收到数据,我的套接字就会发回给客户端。

物有所值…