Stop Loop When Condition Variable (global Var) Changes In Javascript
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"