I’m using node_redis to supply a node service with a JSON representation of objects I get from redis. I think it’s probably relatively basic stuff for a lot of you, but I’m stumped. I get to the point where I send my response before I’ve been through all my hashes and stored them. Here’s the coffeescript:
objects = []
client.keys 'objects*', (err,keys) ->
for key in keys
client.hgetall key, (err,obj) ->
objects.push obj
response.end JSON.stringify objects
and generated JavaScript:
objects= [];
client.keys('objects*', function(err, keys) {
var key, _i, _len, _results;
_results = [];
for (_i = 0, _len = keys.length; _i < _len; _i++) {
key = keys[_i];
_results.push(client.hgetall(key, function(err, obj) {
return objects.push(obj);
}));
}
return _results;
});
return response.end(JSON.stringify(objects));
I don’t know how to put my code on vacation while it waits for the inner stuff to complete. I suspect there is some way to handle it, but I can’t think of anything. Thanks to all.
So you’re iterating over n keys and then returning JSON.stringify(objects) after you call client.keys (which will in turn call client.hgetall for each key?), but then you return response.end(JSON.stringify(objects)) after the call to client.keys.
The problem is simple – you need to render a response inside the function that is appending the result from hgetkeys, but only once you’ve seen all of the responses from hgetkeys.
I’m not a coffeescript buff, but here’s a version in javascript that should work:
I should note, one downside to this is that if you never get a response from one of the hgetall requests, this will timeout and you’ll never emit a response. It might be better to change how you’re storing your hashes so you can get all of the values at once, or have a function that you call after a certain amount of time to emit a response so your client isn’t waiting forever.
May I ask why you chose to write this in coffeescript? It seems like a huge headache to write node when it’s going through a translation layer like that.