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
,它会给你一个undefined
的results
槽。 这是因为在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');