在我的node.js应用程序中,我有以下代码来获取给定用户的最后一个标记。
app.get('/user/:token/mark/last', function(req, res){
var user_token = req.params.id;
// Mark to be returned
var last_mark = 0;
// Get user
var get_user = client.query("SELECT id FROM user where user_token = $1", [user_token]);
// Get mark: handle sensor retrieved
get_user.on('row', function(row) {
get_mark = client.query("SELECT * FROM mark WHERE user_id = $1 order by date desc limit 1", [row.id]);
get_mark.on('row', function(mark) {
last_mark = mark.value;
console.log("LAST MARK:" + last_mark); // OK IT DISPLAYS "LAST MARK:16"
});
// Error checking
get_mark.on("error", function (err) {
console.log("ERROR");
});
});
// Check database errors
get_user.on("error", function (err) {
console.log("NO SUCH USER");
});
// Finalize
get_user.on("end", function () {
console.log("LAST MARK:" + last_mark); // KO IT DISPLAYS "LAST MARK: 0"
});
})
问题是我没有得到正确的“last_mark”(我得到0),好像没有完成任务。
你有什么想法吗?
答案 0 :(得分:1)
这不是我最好的答案,但你可以用一个JOIN替换你的两个查询:
select m.value
from mark m join user u on (m.user_id = u.id)
where user_token = $1
order by m.date desc
limit 1
这应该会让问题消失,让你继续工作。正如莱纳斯所说:
没有问题太大,它无法逃避。
我仍然认为当内部"行准备就绪时会出现某种时间问题"触发事件,外部"查询结束"事件被解雇了。我希望外面的"结束"在内部"行准备就绪之前要触发的事件"事件(但是,诚然,我不熟悉node.js数据库接口)。你也可以推动"处理last_mark
"进入"行的逻辑准备就绪"回调:
get_mark.on('row', function(mark) {
// Call yet another callback to send `mark.value`
// into the outside world.
});
这将在回调链中引入更多步骤,但在处理异步API时,这类事情是相同的。
答案 1 :(得分:0)
小心声明变量,'last_mark
'似乎在全局范围内(或至少在发布的代码之外声明),这可能会导致意外行为,因为回调的异步性质,因为有可能是多个客户端之间的“竞争条件”,可能正在清除并设置相同的全局变量而不是它们自己的本地实例。
// Mark to be returned
var last_mark = 0;