1

I have parts of a larger hash set with the same convention:

redis.hmset("this:that:a", {"one": 'two', "three": 'four'});
redis.hmset("this:that:b", {"five": "six", "seven": "eight"});

var all_parts = {};

redis.keys("this:that:*", function(err, keys) {
  for (var i=0; i<keys.length; i++){
    key = keys[i];

    redis.hgetall(key, function(err, obj) {

      all_parts[key] = obj;

      if (i >= keys.length) {
        return console.log(all_parts);
      } else {
        return console.log('waiting');
      }

    });
  }; 
});

result in the console.log of...

{ 'this:that:a': { five: 'six', seven: 'eight' } }
{ 'this:that:a': { one: 'two', three: 'four' } }

I don't get what's going on, any help is appreciated.

boom
  • 10,856
  • 9
  • 43
  • 64

1 Answers1

3

First, a preliminary comment: you are not supposed to use the KEYS command in user application. This is a O(n) debug command. If you have many keys in Redis, it will freeze the instance at each call.

Now, regarding the program itself, you need to check the scoping rules of Javascript (the ones that apply to closures). Here you access to key variable in the hgetall callback, but it has not been properly captured in a closure (a for loop does not define a closure, you need a function for that).

Here is a possible fix:

redis.hmset("this:that:a", {"one": 'two', "three": 'four'});
redis.hmset("this:that:b", {"five": "six", "seven": "eight"});

var all_parts = {};

redis.keys("this:that:*", function(err, keys) {

  var count = keys.length;
  keys.forEach( function(key) {
    redis.hgetall(key, function(err, obj) {
      all_parts[key] = obj;
      --count;
      if (count <= 0) {
        console.log(all_parts);
      } else {
        console.log('waiting');
      }
    });
  }); 
});

returns:

waiting
{ 'this:that:b': { five: 'six', seven: 'eight' },
  'this:that:a': { one: 'two', three: 'four' } }

See more information at:

hdel inside hget block nodejs redis

nodejs, redis. check if keys exists and create new if not

For loop get items from redis delay

Community
  • 1
  • 1
Didier Spezia
  • 70,911
  • 12
  • 189
  • 154
  • Ok, I see. I was thinking `key` was being passed into `redis.hgetall` scope and then the callback would operate within that scope. Is `redis.hgetall` not a function or am I missing something else AFA scoping. – boom May 16 '13 at 07:11
  • Yes, but you need to define the variable in the scope of the function so it is part of the closure. – Didier Spezia May 16 '13 at 07:31