使用Express将多个数据库查询结果发送到单个视图

时间:2012-12-09 00:19:18

标签: node.js express

我有一个仪表板视图(dashboard.jade),它将显示两个具有不同信息的面板,所有这些信息都应从数据库中检索,然后发送到视图。

假设我有一个定义了两个动作的路径文件(document.js):

exports.getAllDocuments = function(req, res){
    doc = db.model('documents', docSchema);

    doc.find({}, function(err, documents) {
        if (!err) { 
            // handle success
        }
        else { 
            throw err;
        }
    });
};

exports.getLatestDocumentTags = function(req, res){
    tags = db.model('tags', tagSchema);

    tags.find({}, function(err, docs) {
        if (!err) { 
            // handle success
        }
        else { 
            throw err;
        }
    });
};

这些函数只服务于从数据库中检索数据的过程。

现在我想将这些数据发送到我在dashs.index函数下的dashboard.js路径文件的仪表板视图中,在那里我渲染我的仪表板视图。

问题是,由于db调用将是异步的,因此在调用视图之前我无法访问数据。

我想我可以做一个简单地执行所有数据库调用并通过回调的操作一次性将所有数据传递给视图,但这会使我的数据检索操作无法重复使用。

我真的很困惑如何正确解决这个问题,可能我得到这个异步的东西都错了。有人可以给我一些关于如何正确做到这一点的提示吗?

2 个答案:

答案 0 :(得分:5)

这是激起你兴趣的东西。

//Check out the async.js library
var async = require('async');

//Set up your models once at program startup, not on each request
//Ideall these would be in separate modules as wel
var Doc = db.model('documents', docSchema);
var Tags = db.model('tags', tagSchema);

function index(req, res, next) {
    async.parallel({ //Run every function in this object in parallel
    allDocs: async.apply(Doc.find, {}) //gets all documents. async.apply will
    //do the equivalent of Doc.find({}, callback) here
    latestDocs: async.apply(Tags.find, {})
    ], function (error, results) { //This function gets called when all parallel jobs are done
      //results will be like {
      //  allDocs: [doc1, doc2]
      //  latestDocs: [doc3, doc4]
      // }
      res.render('index', results);
    });
}
exports.index = index;
};

尝试更多教程。如果你没有关于异步编程如何在节点中工作的“哈哈”时刻,那么在尝试编写没有指导的全新程序之前,请继续学习指导的手持教程。

答案 1 :(得分:2)

//Check out the async.js library and mangoose model
var mongoOp     =   require("./models/mongo");
var async = require('async');


router.get("/",function(req,res){
    var locals = {};
    var userId = req.params.userId;
    async.parallel([
        //Load user Data
        function(callback) {
             mongoOp.User.find({},function(err,user){
                if (err) return callback(err);
                locals.user = user;
                callback();
            });
        },
        //Load posts Data
        function(callback) {
                mongoOp.Post.find({},function(err,posts){
               if (err) return callback(err);
                locals.posts = posts;
                callback();
            });
        }
    ], function(err) { //This function gets called after the two tasks have called their "task callbacks"
        if (err) return next(err); //If an error occurred, we let express handle it by calling the `next` function
        //Here `locals` will be an object with `user` and `posts` keys
        //Example: `locals = {user: ..., posts: [...]}`
         res.render('index.ejs', {userdata: locals.user,postdata: locals.posts})
    });