此代码崩溃了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');
}
为什么呢?我该如何做到这一点?
答案 0 :(得分:0)
当你在循环中设置timer变量时,循环不等待循环继续之前执行超时。
因此,每次循环发生时都会覆盖超时,并且代码永远不会执行,因为while循环运行代码的时间不会超过一秒。
请点击此处查看类似问题:Wait until a condition is true?
您的代码基本上会更改为以下内容:
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函数以再次执行条件。
答案 1 :(得分:0)
这里有很多基本问题。
首先,我假设你的代码中没有描述某个地方,你实际上是通过传递wait
来调用ms
函数。
您希望在函数done
中可以访问变量timer
和_done
。为确保这一点,您应该在定义函数之前初始化变量。
setTimeout
是异步的。 Javascript是单线程的,除非你不遗余力地启动其他线程(web worker)。 setTimeout
不会冻结处理ms
一段时间。它添加了一个事件,如果没有其他任何执行,它将运行。因为它没有阻塞,你的while循环将再次循环以创建另一个超时,另一个... ad infinium。由于其单线程特性,许多超时都不会中断while循环。它更像是Windows Message Queue。由于_done
不会中断并将done
设置为true,因此它会不断缩短越来越多的超时时间,直到不可避免的崩溃为止。
如果你想延迟一段时间的代码执行,那么你setTimeout
一次,只要没有其他任何东西正在执行,执行就会在等待之后开始。
function _done() {
alert('done!');
}
setTimeout(_done, 1000);
另一个注意事项,我不认为你已经超时clearTimeout
已超时。它仅用于防止在超时之前发生超时。这意味着十分之九,您可以忽略setTimeout的返回值。
答案 2 :(得分:-1)