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