我试图了解这个非阻塞业务。
你能告诉我这里我做错了什么吗?我试图添加一个 retrieveContactName 函数,该函数在写入socket之前从db获取更多信息。我试图让它成为一个回调但我在底部得到错误。
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)
答案 0 :(得分:2)
你的问题归结为没有完全理解范围,基本上问题出现在这里:
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
时,您的预期值不会超出预期值...它很可能会等于results.length
您是undefined
中的results
位置。这是因为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');
});
}
显然这只是一个简单的例子,最好传入实际的结果行 - 取决于你想要/需要的东西。
答案 1 :(得分:0)
结果[i]可能超出回调范围
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');
});
}
});
中断;
你可以在上面放置一个console.log(结果):
sock.write('Conversations '+results[i].session+' '+value+'\n');