Node.js变量范围

时间:2011-06-27 12:57:20

标签: javascript variables node.js

我有一个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 个答案:

答案 0 :(得分:3)

Node.js环境是异步。修改“final”的那些语句是在仅在数据库操作完成时执行的回调内部。在数据库操作开始之后,编写结果的代码会在这些回调运行之前很久就执行。

你几乎已经找不到问题的答案了:在操作完成之前你不能写结果,你知道在回调中就是这种情况。如果你必须等待两者都完成(似乎你这样做),那么你可以做一些事情,比如在外部范围内保留一个计数器。每个回调都可以递增计数器,并且仅当计数器指示两个回调都完成时才调用相同的结果 - 写入器函数。 (我认为Node运行时有一种更好的方式来做这种事情,但我并不熟悉它。在这样的简单情况下,保持像计数器这样的东西很容易做到。)< / p>

另外,一个不相关的注释:“ClientConnectionReady”变量应该可以写成函数定义:

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

或者它应该用var声明。 (事实上​​,我有点意外的是它没有抛出错误,但我再也不熟悉Node.js.)

答案 1 :(得分:2)

从它的外观来看,你试图在为它分配一个值之前写下final。

我假设client.query是异步的。鉴于此,回调函数最有可能在res.writeHeadres.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();
                });
        });                    
};

这样做首先获取行。在该回调中,它然后得到计数。最后,当它工作时,它会在计数回调中将数据发送到客户端。