Hope someone can assist with a (simple) async question on node-redis. I’m trying to load a set from a hash in the redis db and then use that populated set further on. Here’s the code snippet :-
var redis_client = redis.createClient(REDIS_PORT, REDIS_URL);
redis_client.hgetall(target_hash,function(e,o){
Object.keys(o).forEach(function(target){
// get the "name" from the hash
redis_client.hget(o[target],"name",function(e,o){
if (e){
console.log("Error occurred getting key: " + e);
}
else {
redis_client.sadd("newset",o);
}
});
});
// the following line prints nothing - why ??
redis_client.smembers("newset",redis.print);
When I examine the contents of “newset” in redis it is populated as expected, but at runtime it displayed as empty. I’m sure it’s an async issue – any help much appreciated !
hgetallis an asynchronous call: when it receives a reply from the redis server, it will eventually call your callbackfunction (target) { ... }. But within your script, it actually returns immediately. Sincehgetallreturns very fast, Node will immediately run the next statement,smembers. But at this point thesaddstatements haven’t run yet (even if your system is very fast because there hasn’t been a context switch yet).What you need to do is to make sure
smembersisn’t called before all the possiblesaddcalls have executed. redis_client provides themultifunction to allow you to queue up all thesaddcalls and run a callback when they’re all done. I haven’t tested this code, but you could try this:Some libraries have a built-in equivalent of
forEachthat allows you to specify a function to be called when the loop is all done. If not, you have to manually keep track of how many callbacks there have been and callsmembersafter the last one.