jen007
jen007

Reputation: 1589

immediately-invoked function calling setTimeout calling for loop

In the following scenario, event setTimeout get queued and only after stack clears out, i = 3 will print 3 times

//ver1
for (var i = 0; i < 3; i ++ ) setTimeout(()=> console.log(i), 3)

The following will print 1 2 3 in order since i is captured in func x ??

//ver2
for (var i = 0; i < 3; i++) {
    (function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    })(i);
}

Why the following only prints 2 one time?

//ver3
for (var i = 0; i < 3; i++) {
    function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    }(i);
}

I'm mostly confused between ver2 and ver3


EDIT: ver2 explanation can be found here. Any insight on why ver3 only prints 2?

Upvotes: 1

Views: 102

Answers (1)

Bergi
Bergi

Reputation: 664406

Your version 3 doesn't do at all what you think it does. Parenthesis are not optional on an IIFE. But because you named the function, it does get parsed as a function declaration:

for (var i = 0; i < 3; i++) {
    function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    }
    (i);
}

You were never calling x(…) here. The (i) is just an unnecessarily-parenthesised expression evaluating the i variable. Your code executes the same as

for (var i = 0; i < 3; i++) {
    i;
}

So why does this log 2 in the console? Because when you run this on the console, it prints the result value of the statement that was evaluated last: i, which had the value 2 in the last iteration of the loop.

Upvotes: 1

Related Questions