node.js / Postgres: невозможно присвоить значение в области - PullRequest
0 голосов
/ 17 июня 2011

В моем приложении 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 ]

1 голос
/ 20 июня 2011

Это не самый лучший мой ответ, но вы можете заменить два запроса на запрос, содержащий 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

Это должно устранить проблему и позволить вам продолжить работу. Как сказал Линус:

Нет проблем слишком больших, от которых нельзя убежать.

Я все еще думаю, что есть какая-то проблема с синхронизацией, когда запускается внутреннее событие "row ready" и вызывается внешнее событие "request is complete". Я ожидал бы, что внешнее событие «end» будет запущено до внутреннего события «row is ready» (но, по общему признанию, я не знаком с интерфейсом базы данных node.js). Вы также можете вставить логику «сделка с last_mark» в обратный вызов «строка готова»:

get_mark.on('row', function(mark) {
    // Call yet another callback to send `mark.value`
    // into the outside world.
});

Это приведет к дополнительным шагам в цепочке обратных вызовов, но такого рода вещи подходят для курса при работе с асинхронными API.

0 голосов
/ 17 июня 2011

Будьте осторожны с объявлением переменных: «last_mark», по-видимому, находится в глобальной области видимости (или, по крайней мере, объявлено вне вашего опубликованного кода), это может вызвать неожиданное поведение из-за асинхронного характера обратных вызовов, поскольку потенциально«состояние гонки» между несколькими клиентами, которые могут очищать и устанавливать одну и ту же глобальную переменную, а не свои собственные локальные экземпляры.

// Mark to be returned
var last_mark = 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...