node.js / Postgres:无法在范围内分配值

时间:2011-06-17 15:33:45

标签: postgresql node.js

在我的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),好像没有完成任务。

你有什么想法吗?

2 个答案:

答案 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;