sbe*_*eam 5 mongoose node.js express
鉴于mongoose(或sequelize,或redis)查询的异步性质,当你在渲染视图之前需要进行多次查询时,你会怎么做?
例如,您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
});
});
};
Run Code Online (Sandbox Code Playgroud)
所以res.render
在第一个查询回调中,很好.但是等待响应findOne
来看看我们是否了解这个用户呢?它只是有条件地调用,所以我不能放入render
内部回调,除非我为任何一个条件复制它.不漂亮.
我可以想到一些解决方法 -
使它真的异步并在客户端使用AJAX来获取当前用户的个人资料.但这似乎比它的价值更多的工作.
使用Q
和承诺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');
function render() {
res.render('game/index', { title: 'Battle!',
players: players,
game_is_full: (players.length >= 6),
current_user: current_user
});
}
if (req.session.user_id) {
Player.findOne({_id : req.session.user_id}).exec(function(err, player) {
if (err) return;
if (player) {
current_user = player
}
render();
})
} else {
render();
}
});
};
Run Code Online (Sandbox Code Playgroud)
但是,看看你在这里做什么,你可能需要在多个请求处理程序中查找当前的播放器信息,所以在这种情况下你最好使用中间件.
就像是:
exports.loadUser = function (req, res, next) {
if (req.session.user_id) {
Player.findOne({_id : req.session.user_id}).exec(function(err, player) {
if (err) return;
if (player) {
req.player = player
}
next();
})
} else {
next();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以将路由配置为loadUser
在需要req.player
填充的地方进行呼叫,路由处理程序可以直接从那里提取玩家详细信息.
归档时间: |
|
查看次数: |
7354 次 |
最近记录: |