Marco Chiappetta
Marco Chiappetta

Reputation: 53

Javascript: value of variable changes before being used in the callback

I have this piece of code in a module:

    for (var i = 1; i <= n; i++) {
        when = i * 1000;
        track.execute(true, when); // <-- This line calls the method below
    }

And this piece in another module:

this.execute = function(on, when){
    [...]

    var createCallback = function(w){ // <-- Here 'when' should be bound to this function when is called below
        return function(buffers){
            object.doSomething(buffers, w);
        }
    };


    [...] // None of this code modifies when or the callback 'factory'

    this.asyncObj.getBuffer(createCallback(when)); // <-- Binding ?!?
};

The problem is that the value of when is updated at each call, therefore the callback is always executed with the latest value of when, not the one that was set at the time the method was executed (which was the expected behavior).

As you can see I've already tried the hack described in this question: JavaScript closure inside loops – simple practical example but couldn't get it right.

For some reason the callback function above always gets the latest value of when.

Thanks in advance to whoever would like to help!

PS: I guess this happens because the callback is set every time and, thus, every time is set with the latest value of when. But I'm not sure.

UPDATE: here is a tinker to try it out...And it works! O.o http://tinker.io/dee10 (this code reflects the current state of my code locally. It's the same thing as above, anyway).

Upvotes: 0

Views: 1174

Answers (1)

TheJoe
TheJoe

Reputation: 256

As mentioned in the accepted answer of the question you posted, there is not block scope in JS, only function scope. Your attempt doesn't work because you're only returning a new function inside the 'createCallback' function. You need to return a new one each time the 'execute' function is called.

UPDATE Hey Marco, saw your comment. I wasn't able to run the tinker you sent but I copy/pasted the code into jsfiddle and it works fine. Try it out here: http://jsfiddle.net/tKkCh/

You can see that the function is returning with the correct value of 'when' that is passed in each time. That is what you want, right? At least in the fiddle, when you call factory(i)() the code in the fiddle is being evaluated right then, b/c js is a single threaded language.

Perhaps you can try to include more of the other code to help us figure out what's going on... there is probably an issue with the way you are trying to get it to run async in the 'asyncObj'. Thanks, good luck.

Upvotes: 2

Related Questions