Я сыграю здесь некроманта, так как я все еще вижу другой, лучший способ сделать это.
Использование замечательной библиотеки обещаний 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 (и их модели) доступными как функции, возвращающие обещания, с суффиксом Async
(.exec()
становится .execAsync()
и т. Д.). .promisifyAll()
метод является почти универсальным в мире Node.JS - вы можете использовать его для всего, что обеспечивает асинхронные функции, принимающие обратный вызов в качестве последнего аргумента.
Promise.props({
users: users.find().execAsync(),
articles: articles.find().execAsync()
})
.props()
Метод bluebird принимает объект с обещаниями в качестве его свойств и возвращает коллективное обещание, которое разрешается, когда оба запроса базы данных (здесь - обещания) возвращают свои результаты. Разрешенное значение - это наш results
объект в конечной функции:
results.users
- пользователи, найденные в базе данных пользователем mongoose
results.articles
- статьи, найденные в базе данных mongoose (d'uh)
Как видите, мы даже не приближаемся к аду обратного вызова отступа. Оба запроса к базе данных выполняются параллельно - нет необходимости, чтобы один из них ждал другого. Код короткий и читаемый - практически соответствующий по длине и сложности (или, скорее, его отсутствия) желаемому «нерабочему примеру», опубликованному в самом вопросе.
Обещания классные. Используйте их.