首页 文章

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

提问于
浏览
55

我找到的用于渲染具有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
});

可以这样做吗?

6 回答

  • 1

    我有一个函数,我作为返回节点函数使用了很多 .

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

    然后我在所有签名中都有一个可选的回调参数 .

  • 16

    您可以通过以下代码获得所需的结果 . 希望这会帮助你 .

    var async = require('async');
    
    // custom imports
    var User = require('../models/user');
    var Article = require('../models/article');
    
    var List1Objects = User.find({});
    var List2Objects = Article.find({});
    var resourcesStack = {
        usersList: List1Objects.exec.bind(List1Objects),
        articlesList: List2Objects.exec.bind(List2Objects),
    };
    
    async.parallel(resourcesStack, function (error, resultSet){
        if (error) {
            res.status(500).send(error);
            return;
        }
        res.render('home', resultSet);
    });
    
  • 1

    你试图强制实施同步范式 . 只是不工作 . node.js是单线程的,大多数情况下 - 当完成io时,会产生执行上下文 . 通过回调来管理信令 . 这意味着您要么具有嵌套回调,命名函数,要么使用流控制库来使事情更好看 .

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

    我会在这里扮演死灵法师,因为我仍然会看到另一种更好的方法 .

    使用精彩的promise库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() ,依此类推) . .promisifyAll() 方法在Node.JS世界中几乎是通用的 - 你可以在提供异步函数的任何东西上使用它,将回调作为它们的最后一个参数 .

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

    .props() bluebird方法接受带有promises作为其属性的对象,并返回在两个数据库查询(此处为promises)返回其结果时得到解决的集合promise . 已解析的值是最终函数中的 results 对象:

    • results.users - mongoose在数据库中找到的用户

    • results.articles - mongoose(d'uh)在数据库中找到的文章

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

    承诺很酷 . 使用它们 .

  • 1

    简单的方法:

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

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

    但在你的情况下,我认为最简单的方法是嵌套回调(这允许为选定的先前用户提供f.e.quering文章),或者在异步库的帮助下完全并行(参见Flow control / Async goodies) .

  • 20

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

    我检索数据库的功能:

    //读取板 - 完整的DB

    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事件监听器:

    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给我们的承诺,然后一旦我们收到了来自DB的数据,我的套接字将它发送回客户端......

    物有所值...

相关问题