mysql结果循环内的node.js回调

标签 node.js callback

我正在尝试了解这个非阻塞业务。

你能告诉我我在这里做错了什么吗?我尝试添加一个 retrieveContactName 函数,该函数在写入套接字之前从数据库获取更多信息。我尝试将其设为回调,但在底部收到错误。

case 'getConversations':
    var sip  = parts[1];
    var pass = parts[2].replace(/[\n\r]/g, ''); //strip that carriage return
    var sql = "SELECT DISTINCT(session) FROM im WHERE sip = "+connection.escape(sip)+" AND password = "+connection.escape(pass)+" ORDER BY timestamp DESC";
    connection.query(sql, function(err, results) {
        if (err) winston.warn(err);  
        for (var i=0; i < results.length; i++) { 
            retrieveContactName(results[i].session, sip, pass, function(value) {
                sock.write('Conversations '+results[i].session+' '+value+'\n');
            });
        }
    });
break;

其他地方

function retrieveContactName(session, user, pass, callback) {
    var sql = "SELECT `im_from` FROM `im` WHERE `session` = "+connection.escape(session)+" AND `im_to` != "+connection.escape(session)+" AND `sip` = "+connection.escape(user)+"  AND `password` = "+connection.escape(pass)+" LIMIT 1";
    connection.query(sql, function(err, results) {
        if (err) winston.warn(err);  
        if (results.length > 0 ) { 
            callback(results[0].im_from);
        } else {
            callback(session.replace("contact:",""));
        }
    });
}

以及我的错误

TypeError: Cannot read property 'session' of undefined
    at /home/ubuntu/socket/server.js:44:47
    at Query._callback (/home/ubuntu/socket/server.js:79:4)
    at Query.end (/home/ubuntu/socket/node_modules/mysql/lib/protocol/sequences/Sequence.js:75:24)
    at Query._handleFinalResultPacket (/home/ubuntu/socket/node_modules/mysql/lib/protocol/sequences/Query.js:143:8)
    at Query.EofPacket (/home/ubuntu/socket/node_modules/mysql/lib/protocol/sequences/Query.js:127:8)
    at Protocol._parsePacket (/home/ubuntu/socket/node_modules/mysql/lib/protocol/Protocol.js:172:24)
    at Parser.write (/home/ubuntu/socket/node_modules/mysql/lib/protocol/Parser.js:62:12)
    at Protocol.write (/home/ubuntu/socket/node_modules/mysql/lib/protocol/Protocol.js:37:16)
    at Socket.ondata (stream.js:38:26)
    at Socket.emit (events.js:88:20)

最佳答案

您的问题归结为不完全理解范围,基本上问题发生在这里:

for (var i=0; i < results.length; i++) { 
    retrieveContactName(results[i].session, sip, pass, function(value) {
        sock.write('Conversations '+results[i].session+' '+value+'\n');
    });
}

上面的内容不会按您的预期工作,因为当您的回调触发时,i 将不会具有您预期的值...它很可能等于结果。 length 将会在 results 中为您提供一个 undefined 槽。这是因为 for 很可能会在回调发生之前继续执行并完成它的执行。这是非阻塞的原则,代码不会等待,它会继续执行,并且您的回调必须为此做好准备。

为了使用 i 的值或任何可能在回调范围之外更改其值的变量,您需要捕获该值并将其存储在回调中。有几种方法可以做到这一点,但最好的方法是将回调所需的数据作为参数传递 - 因此您需要将 results[i].session (传递到retrieveContactName)传递给您的回调。

function retrieveContactName(session, user, pass, callback) {
    var sql = "SELECT `im_from` FROM `im` WHERE `session` = "+connection.escape(session)+" AND `im_to` != "+connection.escape(session)+" AND `sip` = "+connection.escape(user)+"  AND `password` = "+connection.escape(pass)+" LIMIT 1";
    connection.query(sql, function(err, results) {
        if (err) winston.warn(err);  
        if (results.length > 0 ) { 
            callback(results[0].im_from, session);
        } else {
            callback(session.replace("contact:",""), session);
        }
    });
}

然后:

for (var i=0; i < results.length; i++) { 
    retrieveContactName(results[i].session, sip, pass, function(value, session) {
        sock.write('Conversations '+session+' '+value+'\n');
    });
}

显然这只是一个简单的示例,最好传递实际结果行 - 取决于您想要/需要什么。

关于mysql结果循环内的node.js回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20077538/

相关文章:

javascript - 使用 "eval"创建匿名方法 - 浏览器特定行为

node.js - mocha 的(node.js 测试框架) "it"语句的语义是什么?

reactjs - 向 ReduxReducer 添加回调

node.js - Passport 中的req.isAuthenticated()和passport.authenticate()有什么区别?

javascript - selenium webdriver javascript 查询

javascript:带有回调和 'this' 的原型(prototype)

node.js - onlyoffice nextcloud “document could not be saved” nodeJS-postData错误

asp.net - 如何将回调函数分配给 asp :HyperlinkField?

node.js - Express 4 + pm2 watch 不工作

mysql - 如何使用正则表达式将参数化字符串添加到查询中