4

Experts. Javascript not producing desired delay effect.
From other questions, on SO I got to know that, problem is with settimeout and the way I am using it. But still I am not able to comprehend, how Settimeout works. So I am putting code here. Need to use Javascript only, because of knowledge purpose.
Actually I am trying to clear my concepts about this, closure in javascript. Are they kind of twisted things of Javascript?

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

var no = 100;
while (no != 500) {
    setTimeout(function () {
        size(no, no);
    }, 2000);

    /* it's get executed once, instead of repeating with while loop
    Does it leave loop in mid? I get image with 500px height and
    width, but effect is not acheived.
    */

    no = no + 50;
}

function size(h, w) {
    var objImg = document.getElementsByName('ford').item(0);
    objImg.style.height = h + 'px';
    objImg.style.width = w + 'px';
}
2
  • your while loop is working normal.I've tested it on chrome console. Commented Feb 9, 2013 at 20:34
  • @ramin omrani - true? but Image is not getting resized with delay effect of 2 sec. I know I have messed with SetTimeout, but don't know its inner working fully yet. Commented Feb 9, 2013 at 20:45

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Hi @dystroy - No success yet. Your code makes browser unresponding.
@msinfo my first version was wrong (no incremented in the closure). Can you try the last one ?
yes it did worked. Could you please explain, two iterations of while loop, and values of t and no variable in those conditions. Thanks (With all those multiple edits. :-)
Sorry for the edits (hard to answer with influenza). Do you still need a detailed explanation or is it clear ?
I have now idea of settimeout working, thanks to @daleyjem. but need help with function(no) working. I am just there, but I know I am missing something.
|
3

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';
}

4 Comments

he he he :-) it works your way. Actually I wrote above test code to test my knowledge about settimeout and other things, and here I learnt anothe way of doing it. Would be marking it as answer as soon as someone explains what happened to settimeout in my code. Thanks.
Your code doesn't work the way you think because you're thinking that each setTimeout() will get called once the time passes from the previous setTimeout(). But that isn't so. All of these setTimeout()'s are going to get called immediately at the same time.
Oh! I see, true I was thinking the way you figured out. But oops! since @dystroy gave solution with settimeout option, and he edited multiple times his answer to inform me. I am accepting his answer and up-voting yours.
And like dystroy said... By the time all of those setTimeout()'s get called (which will be at the same time), the value of "no" would have been incremented up to 500 (which would have happened in a matter of milliseconds as soon as the code executed).
0

Your problem is with your size() function syntax & algorithm:

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

var no = 100;

var int = window.setInterval(function () {
    size(no,no);
    no += 50;
},2000)

function size(h, w) {
    if (h == 500){
        window.clearInterval(int);
        return;
    }
    var height = h + 'px';
    var width = w + 'px';
    document.getElementsByName('ford').item(0).style.height = height;
    document.getElementsByName('ford').item(0).style.width = width;
}

http://jsfiddle.net/AQtNY/2/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.