背景资料
我正在尝试编写一些javascript / node.js代码,它们将执行以下操作:
查询redis数据库并从哈希中获取一堆密钥。这就是redis-cli上的命令:
127.0.0.1:6379> hkeys小部件:1231231234 1)“13:00:00_17:00:00_mtwrf” 2)“00:00:00_00:00:00” 3)“08:00:00_12:00:00_mtwrf”
或 127.0.0.1:6379> hkeys小部件:2222222222 1)“00:00:00_00:00:00”
每个小部件至少有一个密钥...称为默认密钥。默认键如下所示:“00:00:00_00:00:00”
对于每个HKEYS查询,如果返回的结果不止一个,我需要根据一组匹配条件测试返回的每个键(默认值除外)。无论哪个键匹配,都是用于对redis进行后续HGET的。例如,在上面显示的第一个结果集中......如果键3匹配,我将运行以下命令:
127.0.0.1:6379> hget widgets:2222222222 08:00:00_12:00:00_mtwrf
"some value"
127.0.0.1:6379>
如果键1或3都不匹配,那么我查询默认键。
代码
我最近发现了异步模块。我目前正在我的代码中使用它来循环HKEYS的结果。 请参阅以下代码:
async.map代码
router.get('/:widgetnum', function(req, res, next) {
//validate widgetnum format
var widgetnum = req.params.widgetnum;
if ( !valid_widget(widgetnum) ) {
var retval = {"res":false, "msg":"malformed widgetnum"};
res.send(JSON.stringify(retval));
} else {
var keys = {};
redis.hkeys("widgets:" + widgetnum, function(err, data){
if (err) {
res.send(JSON.stringify(false));
}
if (data) {
current = getCurrentUTC(); // needed by iterator for match criteria. Using a global variable for now.
async.map(data, hash_iterator, function (err, iterator_results) {
if (iterator_results) {
console.log("it are: " + iterator_results);
}
res.send(iterator_results);
}); //end async map
}
}); //end redis.hkeys
}
});
问题/问题
这是有效的,对于HKEYS返回的每个键,我能够运行“hash_iterator”函数。
但是,一旦进入迭代器函数,在评估/运行每个结果的匹配条件后,我没有运行辅助HGET查询所需的所有信息。
代码:
async.map(data, hash_iterator, function (err, iterator_results)
只传递值:
"13:00:00_17:00:00_mtwrf"
"00:00:00_00:00:00"
"08:00:00_12:00:00_mtwrf"
但是我需要哈希名称(在本例中为“widgets:”)和widgetnum来进行HGET调用。
我想我可以使用全局变量......但我想确保我的方法在这里是正确的。
任何输入都将不胜感激。
这是hash_iterator逻辑:
var hash_iterator = function (redis_key, doneCallBack) {
var results = {};
console.log("processing..." + redis_key);
//skip if default rule....
if (redis_key.indexOf('00:00:00_00:00:00') == -1){
//need to write logic here to do HGET and save
//results somewhere... in case no other keys match
} else {
// run some logic to test match criteria.
if (matchfound) {
console.log("bingo. found match in " + redis_key);
redis.hget(hashname + widgetnum + redis_key, function (e, results){
if (results) {
return doneCallBack(null, results);
} else {
return doneCallBack(null, null);
}
});
}else {
console.log ("no match");
}
}
return results;
}
答案 0 :(得分:0)
您可以使用地图以功能样式解决它。只需生成一对数组,然后将其传递给async.map
从[1,2,3]
您可以生成[['key', '1'], ['key', '2'], ['key', 3]]
所以这里的代码是生成对:
redis.hkeys("widgets:" + widgetnum, function(err, data){
// some code goes here
var pairs = data.map(function(ts) {
return [`widgets:${widgetnum}`, ts];
});
// async.map call goes here
}); //end redis.hkey
在async.map
内部迭代器回调中,您可以使用iterator_results[0]
但在您的情况下,变量widgetnums
不是全局变量。它只是从较高范围变量,如果你在propper范围内定义它,你可以在嵌套函数中使用它。这是一个非常有用的技巧,叫lexical closure。