Shawn31313
Shawn31313

Reputation: 6052

setTimeout is not working correctly inside "for loop"

Now of course, code only does what you make it do.

But i'm confused why in the following code:

var a = {
    0: "Hi",
    1: "Bye"
}

for (var b in a) {
    setTimeout(function () {
        console.log(b);
    }, 1000);
}

Instead of consoling "0" and then "1"

I just get "1" twice.

I'm not sure why that happens. I need a setup like that for a script I am making but I also get the same issue.

Upvotes: 1

Views: 133

Answers (2)

Mulan
Mulan

Reputation: 135197

You can do it this way too

for (var b in a) {
    setTimeout(console.log.bind(console, b), 1000);
}

Or like this

for (var b in a) {
    setTimeout(function(c) {
        console.log(c)
    }.bind(null, b), 1000);
}

Or even like this

// compatibility varies
for (var b in a) {
    setTimeout(function(c) {
        console.log(c)
    }, 1000, b);
}

Upvotes: 1

Arun P Johny
Arun P Johny

Reputation: 388316

it is because your usage of closure is wrong.

In this case you are using the closure variable b inside the setTimeout callback, but the value of the variable b is not looked up until the callback is executed, by then the value of updated to the last value in the object.

One of the solution in such case is the create a local closure as given below

for (var b in a) {
    (function(c){
        setTimeout(function () {
            console.log(c);
        }, 1000);
    })(b)
}

Demo: Fiddle

Upvotes: 4

Related Questions