当javascript中的条件变量(全局变量)发生变化时停止循环

时间:2014-10-10 14:01:06

标签: javascript loops for-loop while-loop

我遇到了一个无法解决的问题。我在javascript中有一个循环,其中要停止的条件变量取决于全局变量。循环开始循环,当我更改该全局变量的值时,它永远不会停止。

stop = false;
var i = 0;
while ((stop == false) && (i<100000)){
    console.log("hi-"+i);
    i++;
}

当循环运行时,如果我执行stop = true,它永远不会停止。我不知道为什么会这样。

有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

JavaScript本质上是单线程的。一旦代码块开始运行,它将在其他任何事情发生之前运行完成。 IE将您stop设置为true的事件在while循环结束后才会执行。

您需要将循环拆分为多个部分并单独运行每个部分,以允许其他事件发生:

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);

这将函数分成多个500个块。 0 {duration}的setTimeout允许函数立即继续(几乎),但会将下一个chunk放在执行链的底部。这允许其他事件发生,因此可以将stop更新为true

Here's a fiddle显示了这种方法。

兼容浏览器中提供的另一种方法是Web Worker,但这已经开始超出此问题的范围。

答案 1 :(得分:0)

您可以尝试使用setInterval .... 把你需要做的事情放到一个函数中并在某个时间间隔调用它... 看看这里......

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);

答案 2 :(得分:0)

听起来你期望JS是多线程的,但事实并非如此,这使某些事情变得非常棒。例如,如果JS是多线程的,那么下面会做什么?

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

JS的答案是&#34;它警告3,&#34;但是如果JS是多线程的,那么在if和alert之间没有什么能阻止另一个线程编辑x,所以它不会被很好地定义。

您可以将控件返回到浏览器的事件循环,同时通过调度该功能确保某些代码可以运行,使用setTimeoutsetInterval 。如果您愿意将该递归的结果变为异步,那么这也允许您在没有大量调用堆栈的情况下执行递归。此外,JS正在获得一项新功能(生成器和yield关键字),这样可以更轻松地暂停&#34;暂停&#34;中间的某个功能只是为了以后再恢复它。

做你正在尝试做的最简单的方法是:

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

您还可以在setTimeout调用中使用非零时间 - 例如人类的反应时间大约是200毫秒,所以如果你只是需要从人的角度来看它是连续的,那么将0更改为100;它会为你的电脑提供更多的呼吸空间。

您也可以使用setInterval但是请注意,如果某些CPU密集型功能暂时阻止其他执行,您将排队一堆所有想要执行的功能相同的功能。另一个。当setTimeout线程调用setTimeout时,有一个最小延迟,由setTimeout强制执行;这不是setInterval的情况(相反,它声称调用之间的平均时间是一致的,但没有声明它们之间的最小或最大延迟)。

为了setInterval,您可能希望在某个点之后停止间隔。当然,在if上添加i检查会使该函数成为空函数,不执行任何操作,因此它不会浪费很多时间,但如果您想要取消计划它,捕获setInterval的结果并将其传递给clearInterval