Отправить несколько запросов к базе данных в одном представлении с помощью 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;
        }
    });
};

Эти функции будут служить лишь частью процесса извлечения данных из базы данных.

Теперь я хотел бы отправить эти данные в представление панели мониторинга из моего файла маршрута dashboard.js в функции exports.index, где я отображаю свое представление панели мониторинга.

Проблема в том, что, поскольку вызовы БД будут асинхронными, у меня не будет доступа к данным до того, как я смогу вызвать представление.

Я думаю, у меня могло бы быть действие, которое бы просто делало все мои вызовы БД и через обратные вызовы доставляло все данные сразу к представлению, но это сделало бы мои действия поиска данных не пригодными для повторного использования.

Я действительно запутался в том, как правильно решить эту проблему, возможно, я неправильно понял эту асинхронную вещь. Может кто-нибудь дать мне несколько советов о том, как сделать это правильно?

2 ответа

Решение

Вот что вас заинтересовало.

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

Попробуйте еще несколько уроков. Если у вас не было момента "ха" о том, как асинхронное программирование работает в узле, продолжайте изучать руководящие, ручные руководства, прежде чем пытаться писать совершенно новые программы без руководства.

//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})
    });
Другие вопросы по тегам