0

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).

6
  • Your code looks fine. Is when really a number? Commented Aug 12, 2013 at 4:28
  • Yeah, that's weird. Do you have a minimal example showing the failure? (JSFiddle, or something?) Commented Aug 12, 2013 at 4:29
  • @bfavaretto Yes, when is a number. :D Commented Aug 12, 2013 at 9:59
  • @skishore I will create a fiddle as soon as I can. Have you seen the PS? Do you think it could be the cause? Commented Aug 12, 2013 at 10:29
  • As I said earlier, the code you posted is fine. The issue maight be something specific about your asyncObj. For example, if getBuffer stores the callback as a property of asyncObj, you'll be overwriting the callback on every call. Commented Aug 12, 2013 at 14:44

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I know there is only function scope, that's why I'm trying to bind when to the w argument in the createCallback. And the created function is always a new one (as you can try here tinker.io/09b6b ). I don't think I understood your point.
thanks a lot for your help. Eventually I changed the whole approach because I couldn't figure it out. I guess there was something else under the hood I didn't consider. Anyway the fiddle and the tinker both work fine so I have no idea what to say. :) I'll take a look at it in the near future but I needed to get it to work asap.

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.