0

I wanted to make a JSFiddle but the code crashes your tab/window... What is wrong with this while loop? It looks right to me...

    var commentLoop = 150;
    var whileLoop = true;
    var count = 0;

    while (whileLoop === true) {
        setInterval(function() {
            console.log("my regular code goes here");
            if (count == commentLoop - 1) {
                console.log("just entered while loop thing");
                whileLoop = false;
            }
            count++;
        }, 500);
    }

What am I missing? Thanks for the help.

2
  • 1
    You can't interrupt the loop. Async code isn't pre-emptive so it must wait for the loop to end before it runs. Commented Jul 30, 2016 at 17:38
  • 1
    See What is the XY Problem Commented Jul 30, 2016 at 17:44

1 Answer 1

1

Because Javascript is single threaded and event driven, as long as your while loop is running, the setInterval() can never fire and its callback will never get called. So you have a deadlock where your while loop just runs forever.

With the event driven nature of Javascript, the setInterval() puts an event into the event queue, but because your while loop never stops running, the interpreter never gets to the point where it can actually finish the current thread of JS execution and pull the next event out of the event queue to run the timer callback.

You cannot use while loop to wait for some other event to happen. In Javascript, the other event can't happen until the while loop itself is done. Instead, you need to use only timers and no while loop. If you can explain a little more clearly what real problem you're trying to solve, we can suggest a coding solution.

To add to the things that are wrong here, you're creating a new setInterval() timer every time through the while loop (so they will pile up with zillions of timers active) so that's messed up too.

You don't say exactly what you're trying to accomplish, but it appears you can use only the interval timer and not the while loop. So, assuming your want to run some operation 150 times, spaced 500ms apart, you could use this:

var count = 0;
var commentLoop = 150;
var timer = setInterval(function() {

    // regular code here

    // check if we're done repeating
    if (count === commentLoop - 1) {
        // stop the timer
        clearInterval(timer);
    } else {
        count++;
    }

}, 500);

Or, this could go into a utility function (you can run this snippet to see it work):

function repeat(numTimes, delay, fn) {
    var cntr = 0;
    var timer = setInterval(function() {
        if (cntr >= numTimes) {
            clearInterval(timer);
        } else {
            // if callback returns true, then stop the timer
            if (fn(cntr) === true) {
                clearInterval(timer);
            }
            ++cntr;
        }
    }, delay);
}

// sample usage
repeat(5, 400, function(cnt) {
    console.log(cnt);
});

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

2 Comments

Expanding on this, the callback passed to setInternal will only be executed after the loop is done, which it is not going to happen.
Added code example.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.