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.

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
Katie
  • 741
  • 1
  • 9
  • 30
  • 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. –  Jul 30 '16 at 17:38
  • 1
    See [What is the XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) –  Jul 30 '16 at 17:44

1 Answers1

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);
});
jfriend00
  • 683,504
  • 96
  • 985
  • 979