1

I have this code:

    for (i = 0; i < 3; i++) {
      var interval = setInterval(function(){
        alert(i);
      }, 2000);
    }

What I would like to achieve is to have an alert every 2 sec displaying first 0, then 1 and lastly 2.

Instead I have to wait for quite long before I have 3 alerts all displaying the number 3. Where is my code wrong?

2

4 Answers 4

1

Well, there is (yet again) more than one solution to this problem. But, lets first talk why your code doesn't work properly.

Your code:

for (i = 0; i < 3; i++) {
    var interval = setInterval(function(){
        alert(i);
    }, 2000);
}

..basically means that it will assign three setInterval calls to be executed after 2 seconds as fast as the for loop is placing them to the queue. So basically, all your calls runs really fast after 2 seconds, only few milliseconds or less between them. Moreover, setInterval means that it will be called as long as clearInterval is called to the variable it is assigned with. In other words, your code never stops executing the alert, because you are never calling clearInterval. Finally, your alert(i) will always display value of 3, because it is the last value of i when execution moves away from the for loop.

To improve your code, you could remove the for loop entirely and just let setInterval run as long as the value of i is alerted three times; At that point, you just call clearInterval to the value which has handle to setInterval and the job is finished.

Working code:

// value to output
var i = 0,
    // starting setInterval and assigning its handle to variable interval,
    // it is used to clear the interval when execution should be finished
    interval = setInterval(function () {

        // alert value of i and increase it by 1
        alert(i++);

        // if i is equals to 3, no more calls
        if(i === 3) {

            // clear the interval so method won't be called in the future
            clearInterval(interval);

        }
    }, 2000);

JS FIDDLE EXAMPLE

Cheers, hopefully you learnt something new today.

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

Comments

1

Without forloop:

var number = 0;
var interval = setInterval(function(){
    alert(number);
    number++;
    if(number === 3) {
        clearInterval(interval);
    }
}, 2000);

JSFIDDLE

Comments

1

1.1 Without for loop + without initial delay (demo):

var i = 0;
var showAlert = function(){
    alert(i);
    i++;
    if(i < 3){
        setTimeout(function(){
            showAlert();
        }, 2000);
    }
};
showAlert();

1.2 Without for loop + with initial delay (demo):

var i = 0;
var showAlert = function(){
    if(i < 3){
        setTimeout(function(){
            alert(i);
            i++;
            showAlert();
        }, 2000);
    }
};
showAlert();

2.1 With for loop + without initial delay (demo):

function setAlert(k){
    setTimeout(function(){
        alert(k);
    },k * 2000);
}
for(var i = 0; i < 3; i++) {
    setAlert(i);
}

2.2 With for loop + with initial delay (demo):

function setAlert(k){
    setTimeout(function(){
        alert(k);
    },(k + 1) * 2000);
}
for(var i = 0; i < 3; i++) {
    setAlert(i);
}

2 Comments

I doubt that you are doing this correctly, your first alert appears without 2 sec wait time.
Well, the Qer should clarify this. The first one needs a delay or not. It's simple to implement.
0
  1. First of all, I would go with setTimout, you know that you want 3 alerts.

  2. Second problem is a bit stranger. You are calling async function, setTimeout/setInterval and referring to the original i of the for loop inside of the setTimeout callback. That will not work because at the time of the timeout invocation the for loop has already finished and i var will be 3. One solution is to wrapp the async function in a self invoking anonymous function with params that you need inside async function. In our case we call it with i.

Solution:

for (i = 0; i < 3; i++) {
    (function(i) {
        setTimeout(function(){
            alert(i);
        }, 2000 * i);
    })(i);
}

JS fiddle

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.