2

I try to output an alert box with the message "hello" every 2 seconds, but only 5 times. So I wrote this code:

var counter = 1;

do {
    setTimeout
    (
        function()
        {
             alert("hello");
             counter++;
        },
        2000
    );
} while( counter <= 5 );

But my page keeps crashing everytime? Why? Whats the best way to add a delay of 2000ms between the alerts?

1

3 Answers 3

6

But my page crashes everytime? Why?

Because the counter is only incremented inside the callback - the loop probably tries to run thousands (if not tens of thousands) of times in that time and quickly runs the browser out of memory. More accurately, as is pointed out in comments, the loop never gives up control to the setTimeout call - so that is never going to get run (Dont worry too much about the distinction here - just accept that your counter is not being incremented)

Whats the best way to add a delay of 2000ms between the alerts

Kick off the next one only as the previous one finishes.

function showHello(i){
  if(i<5){
    setTimeout
    (
        function()
        {
             alert("hello");
             showHello(i+1)
        },
        2000
    );
  }
}

showHello(0);

Related: Is it possible to chain setTimeout functions in Javascript? and how to make a setInterval stop after some time or after a number of actions?

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

11 Comments

"in that time" — It never even gets to that point. The JS event loop is too busy running the while to see if any timers have run out, so it will never hit the timed out function.
The timeout callback is never executed actually, because the loop never gives up control. You could set the delay to 0 and it would still crash.
You're both absolutely accurate, of course. As the OP is struggling with this concept I think we can assume thats going to just confuse them. I have updated the answer nonetheless
@EdwardBlack I meant it does not pause the loop.
@EdwardBlack: This might help learning about JavaScript's execution model: developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop .
|
0

Use setInterval instead:

var counter = 0; // setting the counter
var interval = setInterval(function(){ //setInterval does repeatedly what setTimeout only
                                       //does once
    counter++;
    if(counter === 5){
        clearInterval(interval); //if the counter reaches 5 (the times you asked
                                 //for repeating the alert box) you clear the interval,
                                 //stopping the loop
    }
    alert("hello");
}, 2000);

Here's a working fiddle: https://jsfiddle.net/mwosm34x/

2 Comments

That only answers part of the question and provides no explanation of the solution.
@FelixKling made some comments on the code, hope it's better explained now (I'm new to answering on stackoverflow, still have to perfect answering practices)
0

Use setInterval instead.

And clearInterval() when the counter is greater than 5.

var counter = 1;

var timer = setInterval(function () {
  alert("hello "+counter);
  counter++;
  if (counter > 5) {
    clearInterval(timer);
  }
}, 2000);

1 Comment

"Try this" with no explanation of the code, or what was wrong helps nobody

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.