учитывая асинхронный характер запросов мангуста (или продолжения, или повторения), что вы делаете, когда у вас есть несколько запросов, которые вам нужно сделать перед визуализацией представления?
Например, у вас есть user_id
в сеансе, и вы хотите получить некоторую информацию об этом конкретном пользователе через findOne
. Но вы также хотите отобразить список недавно вошедших пользователей.
exports.index = function (req, res) {
var current_user = null
Player.find({last_logged_in : today()}).exec(function(err, players) {
if (err) return res.render('500');
if (req.session.user_id) {
Player.findOne({_id : req.session.user_id}).exec(function(err, player) {
if (err) return;
if (player) {
current_user = player
}
})
}
// here, current_user isn't populated until the callback fires
res.render('game/index', { title: 'Battle!',
players: players,
game_is_full: (players.length >= 6),
current_user: current_user
});
});
};
Итак, res.render
находится в первом обратном вызове запроса, хорошо. Но как насчет ожидания ответа от findOne
, чтобы узнать, знаем ли мы этого пользователя? Он вызывается только условно, поэтому я не могу поместить render
во внутренний обратный вызов, если только я не продублирую его для любого условия. Не красиво.
Я могу придумать некоторые обходные пути -
сделайте его действительно асинхронным и используйте AJAX на стороне клиента, чтобы получить профиль текущего пользователя. Но это кажется больше работы, чем оно того стоит.
использовать
Q
и обещает дождаться разрешения запросаfindOne
перед рендерингом. Но в некотором смысле это было бы похоже на принудительную блокировку, чтобы заставить ответ ждать моей операции. Не кажется правильным.используйте функцию промежуточного программного обеспечения, чтобы получить информацию о текущем пользователе. Это кажется чище, делает запрос многоразовым. Однако я не уверен, как это сделать, или если это по-прежнему будет проявлять ту же проблему.
Конечно, в более экстремальном случае, если вам нужно сделать дюжину запросов, все может стать ужасно. Итак, каков обычный шаблон с учетом такого типа требований?
async.parallel
для объединения всех результатов? Я попробовал это, и, похоже, это работает, но интересно, хороший ли это подход. У вас, конечно, гораздо меньше запутанности. 06.11.2012async.parallel
здесь не работает. Я обновил свой ответ, включив в него решение промежуточного программного обеспечения, которое, вероятно, лучше подходит для вашего варианта использования. 06.11.2012next()
. 06.11.2012