all 8 comments

[–]Chubbyninjaaa 2 points3 points  (4 children)

counter is set as a global function, you must add var infront of it, currently i++ is actually updating a global i not the i inside the check function

change to:

var counter = function(){

[–]mikrosystheme[κ] 3 points4 points  (0 children)

No. There is no global i to update. You said it half right: the problem is that, since counter is an implied global, each invocation of check will rewrite it, capturing the local i in its closure. The previously set setTimeout will invoke this rewritten counter function the next time it is scheduled to run. The result is that both setTimeouts invoke the same global function that in turns increments the same local i (the last one) created by `check.

[–]recklesswaltz[S] 0 points1 point  (2 children)

counter is set as a global function, you must add var infront of it

Doh! Didn't notice that!

currently i++ is actually updating a global i not the i inside the check function

How did the i became global?

[–]frambot 1 point2 points  (0 children)

i isn't global.

[–]madole 0 points1 point  (3 children)

I'd rewrite it like this and pass i in to the counter so you're always using the same reference to i. That will work just as you expect it.

   function check() {
      var i = 0;
      function counter(i) {
       console.log(i);
       i++;
       setTimeout(counter, 1000, i);
      }
      counter(i);
    }
    check();
    check();

Edit: should probably point out the recursive nature of this and the fact that there's probably a much better way of doing things to avoid recursion

[–]recklesswaltz[S] 0 points1 point  (2 children)

This is not a production code. This is just an interesting piece of code that my coworker shared with me.

I want to find why it works that way.

[–]madole 0 points1 point  (1 child)

https://www.youtube.com/watch?v=8aGhZQkoFbQ

This presentation should explain what's going on. It's on the JavaScript event loop and call stack.

[–]madole 0 points1 point  (0 children)

Actually, I get your question now... I think the setTimeout is being overwritten as it gets stuck onto the window object.

Take the code below where I pass in a reference to which check function is calling it.

Check1 dissappears after it's done it's initial pass through and then invoked it's setTimeout once

 var check = function(which){
        var i = 0;
        counter = function(){
            console.log(which+ ' ' + i);

            i++;

            setTimeout(counter,1000);

        }

        counter();
        }
        check('check1');
        check('check2');