背景资料
我有一个node / express应用程序连接到Redis数据库以查询值列表。然后对于返回数据中的每个值,我需要进行进一步的查询。
问题
初始查询(redis“scan”命令)工作正常,但我尝试初始结果集中每个项目的HGETALL查询的行为不符合预期。
为了演示这个问题,我在第34行添加了一个console.log命令来打印出当前扫描记录的值...然后我在HGETALL的回调函数内再次打印出来(第36行)但是价值观是不同的。在我看来,它们应该是相同的...但我确信它是关于node.js工作方式的基本内容,我很遗憾。
代码
27 router.get('/', function(req, res, next) {
28 redis.send_command("SCAN", [0,"MATCH", "emergency:*"], function(err, reply) {
29 if (reply) {
30 var retdata = [];
31 console.log('length is: ' + reply[1].length);
32 for (var i = 0; i < reply[1].length; i++) {
33 var emergIP = reply[1][i];
34 console.log('emergIP outside the call: ' + emergIP);
35 redis.hgetall(emergIP, function (err, data) {
36 console.log('emergIP inside the call: ' + emergIP);
37 if (data) {
38 var temp = emergIP.split(":");
39 var key = temp[1];
40 console.log('the key is: ' + key);
41 //retdata.push({key:data.callerid});
42 }
43 });
44 }//end for loop
45 res.send(JSON.stringify(retdata));
46 } //end if
47 else {
48 //no emergency data defined yet
49 var retval = {"res":false, "msg":"no emergency data defined"};
50 res.send(JSON.stringify(retval));
51
52 }
53 }); //end send_command
54 });
55
代码输出
length is: 8
emergIP outside the call: emergency:10.1
emergIP outside the call: emergency:10.2
emergIP outside the call: emergency:10.13
emergIP outside the call: emergency:10.14
emergIP outside the call: emergency:10.18.90
emergIP outside the call: emergency:10.19
emergIP outside the call: emergency:10.20
emergIP outside the call: emergency:10.244
GET /emergency/ 200 220.368 ms - 2
emergIP inside the call: emergency:10.244
the key is: 10.244
emergIP inside the call: emergency:10.244
the key is: 10.244
emergIP inside the call: emergency:10.244
the key is: 10.244
emergIP inside the call: emergency:10.244
the key is: 10.244
emergIP inside the call: emergency:10.244
the key is: 10.244
emergIP inside the call: emergency:10.244
the key is: 10.244
emergIP inside the call: emergency:10.244
the key is: 10.244
emergIP inside the call: emergency:10.244
the key is: 10.244
问题
我认为问题在于我期望send_command函数的回调按顺序发生。换句话说,也许问题是我不应该在另一个函数调用中进行函数调用? 这是我的第一个节点应用程序......我正在学习。
任何建议将不胜感激。
答案 0 :(得分:0)
您可以利用闭包和立即调用的函数,而不是使用async.forEach:
// get all elements from redis
function getAll(emergIP, callback) {
redis.hgetall(emergIP, function (err, data) {
if (err) {
return callback(err);
}
console.log('emergIP inside the call: ' + emergIP);
if (data) {
var temp = emergIP.split(":");
var key = temp[1];
console.log('the key is: ' + key);
}
return callback(null, data);
});
}
// Iterate all over the results
function getResults (reply, callback) {
var retdata = [];
console.log('length is: ' + reply.length);
var length = reply.length;
if (!length) {
return callback(null, retdata);
}
for (var i = 0; i < length; i++) {
var emergIP = [i];
console.log('emergIP outside the call: ' + emergIP);
(function (emergIP, i) {
getAll(emergIP, function (err, data) {
if (err) {
// @todo: how would you like to handle the error?
}
retdata.push({key:data.callerid});
if (i === length - 1) {
return callback(null, retdata);
}
});
}(emergIP, i));
} //end for loop
}
router.get('/', function (req, res, next) {
redis.send_command("SCAN", [0, "MATCH", "emergency:*"], function (err, reply) {
if (reply) {
getResults(reply[1], function (err, data) {
if (err) {
// @todo: how would you like to handle this in case of error?
}
res.send(JSON.stringify(data));
});
} //end if
else {
//no emergency data defined yet
var retval = { "res": false, "msg": "no emergency data defined" };
res.send(JSON.stringify(retval));
}
}); //end send_command
});
<强> 修改 强>
我已经修改了一些代码,以便在迭代完成时返回json。它不是完美的代码,因为在这种情况下如果没有迭代结果,它根本不会返回对客户端的响应。考虑使用async.each:http://caolan.github.io/async/docs.html#.each
<强> EDIT2 强>
我试图将代码分离并将其拆分为函数。您可以将这些功能移动到另一个文件,然后将它们放入路由器。很抱歉,如果有任何错字导致代码无法正常运行,我实际上并没有尝试运行它。