【问题标题】:nodejs getting db delayed result only works with console.lognodejs 获得 db 延迟结果仅适用于 console.log
【发布时间】:2014-08-22 15:40:03
【问题描述】:

我知道节点的事件驱动/非阻塞的东西,我已经使用了大约 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() 函数无效的任何想法......

【问题讨论】:

  • 你在哪里检查 dbRows2 '在程序结束'?因为查询是异步的,所以程序端必须等待查询完成,然后再检查 test 中分配的结果。
  • 检查在程序结束...我将编辑示例以添加它...

标签: node.js asynchronous closures


【解决方案1】:

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

程序流程如下所示:

  • connect 被调用并排队
  • 查询被调用并排队
  • 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 );
}

【讨论】:

  • 感谢您的回答,但是不应该在程序结束之前将 test() 函数(设置 dbRows2 )排队并“满足”...?我们如何解决这个问题... (不加载任何额外的库)
  • 当您说“检查在程序结束时...”时,我假设您的意思是作为模块中的最后一条语句,而不是在所有其余逻辑完成执行时。如果不确切知道代码的结构,很难给出明确的答案,但基本的解决方案是在查询回调中放置或调用取决于查询是否完成的逻辑。我将添加一个示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
  • 2023-04-05
  • 2011-12-19
  • 1970-01-01
相关资源
最近更新 更多