Question

I'm trying to get a bunch of keys from a redis instance. I'm using node-redis. I'm using a loop:

for( var i=1; i<=num; ++i ){
    client.get(key + ':' + num, function (err, reply) {
        obj[num] = reply;
    });
}
return obj;

But obj is just undefined. I feel like I may be having problems because get is obviously called asynchronously. Is there another way to achieve this? Should I just store the values in a sorted set instead?

Était-ce utile?

La solution

I'm going to hazard a guess based on the coding interface and your comments that client.get() is asynchronous. That means that it calls the callback function passed to it "sometime later", not immediately. Thus, you can't use synchronous coding patterns to collect the results from multiple calls to client.get() because the results in obj are not yet available when your function returns. Thus obj is not yet populated with the results.

If you want to know when multiple asychronous calls are done, then you have to code a very different way. And, the results will ONLY be available inside the callback functions, not at the end of your function.

In all, I see multiple problems with your code:

  1. client.get() is asynchronous so it hasn't finished yet when your function returns
  2. You should probably be using i, not num in your client.get() call so that each time through the for loop generates a different request.
  3. The value of i in the loop has to be frozen in a closure in order to retain it's value for use in the callback function that is called later.
  4. If obj was actually undefined, then that may be because you didn't initialize it to an empty object.

Here's one way to do it:

var obj = {};
var remaining = num;
for( var i=1; i<=num; ++i ){
    // create a closure here to freeze the value of i in the callback
    (function(i) {
        client.get(key + ':' + i, function (err, reply) {
            obj[i] = reply;
            // see if all asynch calls are done yet
            --remaining;
            if (remaining === 0) {
                // all asynch calls to client.get() are done now
                // in here, you can use the obj object and the results put on it
            }
        });
    })(i);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top