Skip to content Skip to sidebar Skip to footer

Stop Loop When Condition Variable (global Var) Changes In Javascript

I'm having a problem that I can't solve. I have a loop in javascript where the condition variable to stop depends on a global variable. The loop starts looping and when I change th

Solution 1:

JavaScript is inherently single threaded. Once a block of code has started running, it will run to completion before anything else happens. IE the event where you're setting stop to true will not execute until after the while loop has finished.

You need to split your loop into sections and run each section individually, allowing other events to take place:

stop = false;
var i = 0;

function loopLogic() {
  var tempStop = i + 500;
  while (i < tempStop) {
    //original processing logic
    console.log("hi-" + i);
    i++;
  }

  if (!stop && i < 100000)
    window.setTimeout(loopLogic, 0);

}
window.setTimeout(loopLogic, 0);

This breaks up the function into multiple chunks of 500 at a time. The setTimeout of 0 duration lets the function continue (almost) immediately, but will put the next chunk at the bottom of the execution chain. This allows other events to happen and therefore will allow updating of stop to true

Here's a fiddle showing this approach.

The other approach available in compliant browsers is the Web Worker, but that's starting to get beyond the scope of this question.


Solution 2:

You can try using the setInterval.... Put what you need to do into a function and call it at some interval... Take a look here...

http://jsfiddle.net/o5mnb7jv/1/

var stop = false;
var obj = document.getElementById("btn").addEventListener("click", function(){
    stop = true;
});
var interval;
function loop(){
    var result = document.getElementById("result");
    if(!stop){
        result.innerHTML = "Running...";
    }else{
        clearInterval(interval);
        result.innerHTML = "Stopped...";
    }
}
interval = setInterval(loop, 500);

Solution 3:

It sounds like you were expecting JS to be multithreaded, but it is not, which makes certain things awesome. For example, if JS were multithreaded, what would the following do?

if (x === 3) {
    alert(x);
}

The answer in JS is "it alerts 3," but if JS were multithreaded, there would be nothing stopping another thread from editing x between the if and the alert, so it wouldn't be well-defined.

You can return control to the browser's event loop while making sure that some code will run, by scheduling that function, either with setTimeout or setInterval. This also lets you do recursion without a massive call stack, if you're willing for the result of that recursion to be asynchronous. Furthermore JS is getting a new feature (generators and the yield keyword) which will make it easier to "pause" a function somewhere in the middle only to resume it later.

The simplest way to do what you're trying to do is:

var i = 0, running = true;
function iter() {
    if (running && i < 100000) {
        console.log("hi", i++);
        setTimeout(iter, 0);
    }
}
iter();

You can also use a non-zero time in the setTimeout call -- e.g. the human reaction time is something like 200ms so if you just need it to seem continuous from a human perspective, change the 0 to 100; it'll give your computer a little more space to breathe.

You can also use setInterval but just be aware that if some CPU-intensive function blocks other execution for a while, you'll queue up a bunch of the same function that all want to execute one after another. When a setTimeout thread calls setTimeout, there is a minimum delay which is enforced by setTimeout; this is not the case with setInterval (which claims instead that the average time between calls is consistent, but makes no claims about the minimum or maximum delays between them).

For the sake of setInterval you will probably want to stop the interval after some point. Adding the if check on i of course makes the function an empty function which does nothing, so it doesn't waste much time, but if you want to unschedule it, capture the result of setInterval and pass it to clearInterval.


Post a Comment for "Stop Loop When Condition Variable (global Var) Changes In Javascript"