0

How do you access parent scope from a callback. The callback is function (err, obj). The var to_user_id is the same in all iterations. It looks like the callbacks are processed after all the iterations are done so the var to_user_id is only one value for all callbacks.

for(var i = 0, len = keys.length; i < len; i++) {

  to_user_id = keys[i].replace('m', '')

  client.get(keys[i], function (err, obj) {
    //var not updating, why is both to_user_id=77
    console.log("match: to_user_id=" + to_user_id + " from_user_id=" + obj)
    var match = "match: to_user_id=" + to_user_id + " from_user_id=" + obj
    io.emit(1, match);
  });

}

Output

See how to_user_id is 77 for both iterations. One should be 6 and the last should be 77.

match: to_user_id=77 from_user_id=77

match: to_user_id=77 from_user_id=6

client.get is a redis function just in case you're wondering.

2 Answers 2

1

Your client.get() calls are asynchronous. As such, the for-loop finishes before any of the client.get() callbacks are executed. That means that to_user_id will be set to keys[keys.length - 1].replace('m', '') by the time the first client.get() callback is executed. So that is the reason why you are seeing the same to_user_id in your output.

The fix here is to use a closure to capture the current value of to_user_id. The simplest way of doing this is to use keys.forEach():

keys.forEach(function(key) {
  to_user_id = key.replace('m', '')

  client.get(key, function (err, obj) {
    console.log("match: to_user_id=" + to_user_id + " from_user_id=" + obj)
    var match = "match: to_user_id=" + to_user_id + " from_user_id=" + obj
    io.emit(1, match);
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

Ahh. The closure is created inside the forEach.
I ended up using your code because I couldn't resist how succinct it was. Javascript is almost as beautiful as Ruby.
1

You must to create closure to save value of i variable.

for (var i = 0, len = 5; i < len; i++) {
  (function(i, to_user_id) {
    client.get(i, function(err, obj) {
      io.emit("match: to_user_id=" + to_user_id + " from_user_id=" + obj)
    });
  }(i, keys[i].replace('m', '')));
}

1 Comment

Awesome. You're a JS genius.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.