Javascript SetTimeout and Loops [duplicate]

Solution 1:

You have two problems :

  • no will have the value of end of loop when the callback is called
  • you're programming all your timeouts 2000 ms from the same time, the time the loop run.

Here's how you could fix that :

var t = 0
while (no != 500) {
   (function(no) {
      t += 2000;
      setTimeout(function() { size(no,no);} ,t);
   })(no);
   no  = no+50; // could be written no += 50
}

The immediately executed function creates a scope which protects the value of no.


A little explanation about (function(no) { :

The scope of a variable is either

  • the global scope
  • a function

The code above could have been written as

var t = 0
while (no != 500) {
   (function(no2) {
      t += 2000;
      setTimeout(function() { size(no2,no2);} ,t);
   })(no);
   no += 50;
}

Here it's probably more clear that we have two variables :

  • no, whose value changes with each iteration and is 500 when the timeouts are called
  • no2, in fact one variable no2 per call of the inner anonymous function

Each time the inner anonymous function is called, it declares a new no2 variable, whose value is no at the time of call (during iteration). This variable no2 is thus protected and is used by the callback given to setTimeout.

Solution 2:

Why not just use setInterval() instead?

var objImg = new Object();
var h;
var w;

var no = 100;
var myInterval = window.setInterval(function() {
    size(no, no);
    no = no + 50;
    if (no >= 500) clearInterval(myInterval);
}, 2000);

function size(h, w) {
    var objImg = document.getElementsByName('ford').item(0);
    objImg.style.height = h + 'px';
    objImg.style.width = w + 'px';
}