nodejs获取db延迟结果仅适用于console.log

时间:2014-07-02 00:20:10

标签: node.js asynchronous closures

我知道节点的事件驱动/非阻塞内容,我已经使用它大约2年了... 最近我遇到了这个问题,即使强行关闭也无法解决它......

我要求数据库提供一个简单的结果:'SELECT 1 + 1 as theResult'

(...)  // previous code

var dbRows1 = {};  // empty object to hold rows
var dbRows2 = {};  // idem

var mysql = require( 'mysql' );
var db = mysql.createConnection( dbInfo );  // dbInfo has connction data

var test = function( a ) { dbRows2 = a };

db.connect( 
    function( err ) 
        { 
        if (err) throw err.stack; 
        console.log( 'TID ->', db.threadId) 
        });

db.query ( 
    'SELECT 1+1 AS XXX',
    function( err, rows, fields ) 
            {
            console.log( 'rows ->', rows );  // works ok
            dbRows1 = rows;  // don't work because rows is still empty
            test( rows );  // !!!should work but dbRows2 is empty at program end!!!

            });

(...) // more code

console.log( dbRows2 );

最后一行打印dbRows2({})的空对象...

任何想法为什么console.log()工作,我的test()函数不起作用......

1 个答案:

答案 0 :(得分:0)

您的测试功能正在运行,问题是,在您的上一个console.log语句执行时,测试功能尚未执行。这是因为.connect.query都是异步的。

程序流程如下所示:

  • 连接被调用并排队
  • 查询被调用并排队
  • 调用console.log(dbRows2)
  • (时间过去了......)
  • 连接成功并回拨
  • (时间过去了......)
  • 查询成功并回调
  • 测试称为将行分配给dbRows2

您可以通过在每个操作之前和回调内部在代码中放置一些策略日志来自行验证此行为。如果你这样做,你会在你的控制台中看到类似的东西:

about to call connect
about to call query
logging dbRows2
connect succeeded
query succeeded
about to call test

在不知道代码的确切结构的情况下,下面提供了一个粗略的示例,说明如何构造逻辑以确保仅在查询完成后调用依赖于查询完成的代码:

db.query ( 
    'SELECT 1+1 AS XXX',
    function( err, rows, fields ) 
            {
            console.log( 'rows ->', rows );  // works ok
            dbRows1 = rows;  // don't work because rows is still empty
            test( rows );  // !!!should work but dbRows2 is empty at program end!!!

            // Call doStuffThatDependsOnQuery here
            doStuffThatDependsOnQuery();
            });

(...) // more code that doesn't depend on db.query(...)

function doStuffThatDependsOnQuery() {
    console.log( dbRows2 );
}