[英]javascript settimeout never fires function and crashes chrome
这段代码会使Chrome崩溃:
var ms = 1000;
function wait(ms) {
function _done() {
done = true;
alert('timer: ' + timer + ', done: ' + done);
clearTimeout(timer);
}
var done = false;
var timer;
alert('starting timer');
while (!done) {
timer = setTimeout(_done, ms);
}
alert('wait done');
}
为什么? 我该如何正确处理?
当您在循环内设置计时器变量时,循环在循环继续之前不会等待超时执行。
因此,每次循环发生时,您都将覆盖超时,并且代码将永远不会执行,因为您的while循环运行时间不会超过一秒钟。
看到类似的问题在这里: 等到条件为真?
您的代码本质上将变为以下内容:
var ms = 1000;
var done = false;
var timer;
function _done() {
done = true;
alert('timer: ' + timer + ', done: ' + done);
clearTimeout(timer);
wait(ms);
}
function wait(ms) {
if(!done) {
alert('starting timer');
timer = setTimeout(_done, ms);
} else {
//Is Done...
}
}
一旦调用了wait函数,它将检查done
变量是否为true,否则,它将调用_done
函数将其设置为true。 然后_done
函数将重新调用wait函数以再次执行条件。
这里有很多基本问题。
首先,我假设您的代码中未描述的某个地方,实际上是通过传递ms
调用wait
函数的。
看来您希望变量done
并且可以在函数_done
访问timer
。 为确保这一点,您应在定义函数之前初始化变量。
setTimeout
是异步的。 除非您不愿意启动其他线程(网络工作者),否则Javascript是单线程的。 setTimeout
不会在ms
时间内冻结处理。 它添加了一个事件,如果没有其他任何执行,该事件将运行。 因为它没有阻塞,所以while循环将再次循环以创建另一个超时和另一个... ad infinium。 由于单线程性质,许多超时都不会中断while循环。 它更像Windows消息队列。 由于_done
不会中断并且将done
设置为true,因此它将不断产生越来越多的超时,直到不可避免的崩溃。
如果您希望将代码执行延迟一定的时间,则只需设置一次setTimeout
,只要没有其他任何执行,则将在等待之后开始执行。
function _done() {
alert('done!');
}
setTimeout(_done, 1000);
另外请注意,我认为您不必为已经超时的超时而清除clearTimeout
。 它仅用于防止超时之前发生超时。 这意味着十分之九可以忽略setTimeout的返回值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.