mysql结果循环中的node.jscallback

我试图让我的头在这个非阻塞业务。

你能告诉我我在这里做错了吗? 我试图添加一个retrieveContactName函数,在写入套接字之前从db获取更多信息。 我试图使它callback,但我得到的底部的错误。

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'); }); } 

以上将不会像你期望的那样工作,因为当你的callback触发时, i将不会得到你期望的值…它很可能等于results.length ,它会给你一个undefinedresults槽。 这是因为在callback发生之前, for很可能会继续执行并完成执行。 这是非阻塞的原则,代码不会等待,它继续,你的callback必须为此做好准备。

为了使用i的值或任何可能在callback范围之外改变其值的variables,您需要捕获该值并将其与callback一起存储。 有几种方法可以做到这一点,但最好的方法是将callback中所需的数据作为parameter passing – 所以您需要将results[i].session (传递到retrieveContactName)传递到您的callbackresults[i].session

 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'); }); } 

显然,这只是一个简单的例子,最好传递实际的结果行 – 取决于你想要什么。

结果[i]可能超出callback范围内的范围

 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');