Node.js Область действия переменной - PullRequest
1 голос
/ 27 июня 2011

У меня есть настройка http-сервера, которая в основном должна выполнять поиск в базе данных.

Вот фрагмент кода:

var sys = require('sys');
var Client = require('mysql').Client;
var client = new Client();

client.host = '_';
client.user = '_';
client.password = '_';
client.database = '_';
var http = require('http');
http.createServer(function(req, res) {
    req.on('end', function() {
        client.connect(function(error, results) {
            if (error) {
                console.log('Connection Error:');
                return;
            }
            ClientConnectionReady(client);
        });
        ClientConnectionReady = function(client) {
            var final = '';
            client.query('select * from table', function selectCb(error, result, fields) {
                if (error) {
                    console.log('ERROR');
                    client.end();
                    return;
                }
                final += "{" + JSON.stringify(result);

            });
            client.query("SELECT    COUNT(*) from table", function selectCb(error, result, fields) {
                if (error) {
                    console.log('ERROR');
                    client.end();
                    return;
                }
                final += "," + JSON.stringify(result) + "}";
            });
            res.writeHead(200, {
                'Content-Type': 'text/plain'
            });
            res.write(final);
            res.end();
            client.end();
        };
    });
}).listen(8007, "127.0.0.1");
  

Если я распечатаю значения переменной 'final 'в местах, где я их назначаю, я вижу допустимые значения, но в строках, когда я делаю' res.write (final) ', final все еще пуст.

Как мне заставить это работать и почему это терпит неудачу ??Спасибо за помощь, я новичок в node.js

Ответы [ 2 ]

3 голосов
/ 27 июня 2011

Среда Node.js асинхронная . Те операторы, которые изменяют «final», находятся внутри обратных вызовов, которые выполняются только после завершения операций базы данных. Код сразу после инициализации операций базы данных, в которые вы записываете результат, выполняется задолго до выполнения этих обратных вызовов.

Вы уже почти наткнулись на ответ на проблему: вы не должны записывать результат до завершения операций, что, как вы знаете, будет иметь место в обратных вызовах. Если вам нужно дождаться окончания обоих (кажется, что вы это делаете), то вы можете сделать что-то вроде удержания счетчика во внешней области видимости. Каждый обратный вызов может увеличивать счетчик и вызывать одну и ту же функцию записи результатов только тогда, когда счетчик показывает, что оба обратных вызова завершены. (У меня есть идея, что у среды выполнения Node есть более причудливый способ делать подобные вещи, но я не настолько знаком с этим. В простом случае, подобном этому, сохранить что-то вроде счетчика достаточно просто.)

Кроме того, несвязанное примечание: эту переменную «ClientConnectionReady», вероятно, следует записать как определение функции:

function ClientConnectionReady(client) {
  // ...
}

или это должно быть объявлено с var. (Я немного удивлен тем, что это не выдает ошибку, но опять же я не так хорошо знаком с Node.js.)

2 голосов
/ 27 июня 2011

Судя по всему, вы пытаетесь написать final до того, как ему когда-либо будет присвоено значение.

Я предполагаю, что client.query является асинхронным.Учитывая это, функция обратного вызова, скорее всего, вызывается после строк res.writeHead и res.write.То, что вам нужно сделать, это поместить другие вызовы и строки client.write* в первый обратный вызов.

Это должно дать вам представление (не проверял, компилируется ли оно)

ClientConnectionReady = function(client)
{
    var final = '';

    //Get the rows
    client.query('select * from table',
        function selectCb(error, result, fields) 
        {
            if (error) 
            {
                console.log('ERROR');
                client.end();
                return;
            }
            final+="{"+JSON.stringify(result);

            //Get the count query
            client.query("SELECT COUNT(*) from table",
                function selectCb(error, result, fields) 
                {
                    if (error) 
                    {
                        console.log('ERROR');
                        client.end();
                        return;
                    }

                    final+=","+JSON.stringify(result)+"}";

                    //Return the final results to the client now
                    res.writeHead(200, {'Content-Type': 'text/plain'});
                    res.write(final);
                    res.end(); 
                    client.end();
                });
        });                    
};

То, что это делает, сначала получает строки.В этом обратном вызове он получает счетчик.Наконец, когда это работает, он отправляет данные клиенту в обратном вызове count.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...