Reputation: 420
Consider the following code:
if(connections.hasOwnProperty(id)){
console.log('client '+id+' is connected. querying redis.');
id = id;
redisClientActor.lrange("NOTIFICATIONS_"+id, 0, 0, function(err, reply) {
if(reply !== null && reply !== undefined){
console.log(JSON.stringify(Object.keys(connections)));
connections[id].sendUTF(reply);
console.log('Forwarded notification to client '+id);
}else{
console.log(err);
}
});
}else{
console.log('Received notification, but client '+id+' not connected.')
}
it's part of a very basic notification server written in NodeJS. It's using the redis npm package. Because of the asynchronous nature of Node I understand why the code is unable to work currently (id is out-of-scope which leads to sendUTF failing which leads to the script crashing).
If lrange was a self-defined function I'd simply add a third parameter here and be done with it. But since it isn't I struggle to find the solution as to how access "id" inside of the lrange callback (l5 and following)
I'd be very grateful for a quick hint in the right direction.
Upvotes: 1
Views: 143
Reputation: 11819
In case you are iterating through a loop that alters the value of "id", the callbacks would all see the last value of "id" which was assigned to it during the last iteration.
In that case you need to capture the value of id with a closure:
var produceClosureForId = function(id){
return function(err, reply) {
if(reply !== null && reply !== undefined){
console.log(JSON.stringify(Object.keys(connections)));
connections[id].sendUTF(reply);
console.log('Forwarded notification to client '+id);
}else{
console.log(err);
}
};
}
redisClientActor.lrange("NOTIFICATIONS_"+id, 0, 0, produceClosureForId(id) );
Upvotes: 1