我遇到了一个无法解决的问题。我在javascript中有一个循环,其中要停止的条件变量取决于全局变量。循环开始循环,当我更改该全局变量的值时,它永远不会停止。
stop = false;
var i = 0;
while ((stop == false) && (i<100000)){
console.log("hi-"+i);
i++;
}
当循环运行时,如果我执行stop = true,它永远不会停止。我不知道为什么会这样。
有什么想法吗?
谢谢!
答案 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,所以它不会被很好地定义。
您可以将控件返回到浏览器的事件循环,同时通过调度该功能确保某些代码可以运行,使用setTimeout
或setInterval
。如果您愿意将该递归的结果变为异步,那么这也允许您在没有大量调用堆栈的情况下执行递归。此外,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
。