Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery and setTimeout inside For loop [duplicate]

I just encountered a very weird issue (I fixed it though) but I wanted to know why did it happen in the first place:

function stuffAppear() {
    var i;
    for (i = 0; i < speech.length; i++) {
        apperance(i);
    }
}
function apperance(i) {
    var x = speech[i];
    setTimeout(function() {$(speech[i]).fadeIn(1000); console.log(i);}, 1000 + i * 1500);
    console.log(speech[i]);
}

The console log shows "#yo0" then "#ma0b" (which is the required) but at the same time, they never faded in

I played around with the code until I reached this:

function stuffAppear() {
    var i;
    for (i = 0; i < speech.length; i++) {
        apperance(i);
    }
}
function apperance(i) {
    var x = speech[i];
    setTimeout(function() {$(x).fadeIn(1000); console.log(i);}, 1000 + i * 1500);
}

And that did the trick, but I don't know why the first code didn't work. Can someone explain that to me, please? And thank you!

like image 728
Mathspy Avatar asked Apr 06 '14 08:04

Mathspy


1 Answers

In a JSFiddle both versions work fine (and the same):

First: http://jsfiddle.net/TrueBlueAussie/Bkz55/3/

var speech = ["#yo0", "#ma0b", "#blah"];

function stuffAppear() {
    var i;
    for (i = 0; i < speech.length; i++) {
        apperance(i);
    }
}
function apperance(i) {
    var x = speech[i];
    setTimeout(function() {$(speech[i]).fadeIn(1000); console.log(i);}, 1000 + i * 1500);
    console.log(speech[i]);  // <<< THIS WOULD OCCUR IMMEDIATELY
}

Second: http://jsfiddle.net/TrueBlueAussie/Bkz55/4/

var speech = ["#yo0", "#ma0b", "#blah"];

function stuffAppear() {
    var i;
    for (i = 0; i < speech.length; i++) {
        apperance(i);
    }
}
function apperance(i) {
    var x = speech[i];
    setTimeout(function() {$(x).fadeIn(1000); console.log(i);}, 1000 + i * 1500);
}

So I suspect what you are seeing is a side effect of your other code (not shown).

The only odd thing is you were logging in the first version twice (once outside the setTimeout which would display at the start - as you mentioned)

Follow up:

Having now seen the real code, the cause was changing of the speech array during the timeouts. When the timeout function was finally hit the speech array was empty!

like image 97
Gone Coding Avatar answered Sep 28 '22 13:09

Gone Coding