假设您要使用setTimeout创建一个java函数,以便每5秒重复一次。这个定时功能只是更新一些数据。当用户单击打开叠加层的按钮时,会发出呼叫,只要叠加层打开,该功能就会继续运行。覆盖关闭后,abandonUpdate设置为true,并在计时器功能中进行检查。但是,如果用户在超时完成之前打开覆盖,它将添加另一个超时功能实例。
如何避免这种情况?
(顺便说一下,计时器似乎不适用于jsfiddle或bin ..但是我的服务器上的代码相同但是..)
var abandonUpdate = true;
function timers(){
if(!abandonUpdate){
$('.timeout').css({"background-color":'#'+(Math.random()*0xFFFFFF<<0).toString(16)});
setTimeout("timers()", 5000);
}
}
$('.timeout').click(function(){
abandonUpdate = false;
console.log("Hello I'm running");
timers();
});
答案 0 :(得分:2)
让我们看一下直接演示:
var loops = 0,
to = setTimeout(function test(){
console.log('Test run ' + ++loops + ' times.');
if (loops < 100) {
to = setTimeout(test, 3000);
}
}, 3000),
check = setTimeout(function check(){
console.log('Test checked (' + loops + ').');
if (loops > 10) {
console.log('Test setTimeout aborted.');
clearTimeout(to);
return;
}
setTimeout(check, 500);
});
我们这里有两个再生setTimeout()
,每个都有一些不同的东西。第一个是使用var to
运行test()
功能,这是我们试图抢占的功能(或者如果你愿意,可以中止)。
第二个var check
更频繁地运行(1/2秒而不是3秒)。第二个是监控test()
和&#34;取消&#34;的迭代。 (或&#34;清除&#34;)test()
超时,使用捕获的参考var to
。
请注意我在重新生成超时时如何在test()
内捕获引用?如果你不这样做,你会得到一个无限循环; setTimeout()
返回的每个引用都会发生更改,因此您必须小心捕获对两个函数都可以访问的同一变量的引用。否则,你&#34;清除&#34;可能/可能已经结束的超时。
当然,另一种方法是使用setInterval()
,在运行时始终使用相同的引用,因此clearInterval(to)
可以正常运行,而且您不会使用to
。我不得不担心将setInterval()
设置为正确的引用。我会考虑这个优惠;在这里使用setTimeout()
,而不是var intl;
function timers() {
$('.timeout').css({
"background-color": '#' + (Math.random() * 0xFFFFFF << 0).toString(16)
});
}
$('.timeout').click(function(){
if (intl) {
clearInterval(intl);
console.log("I stopped goodbye!");
intl = 0;
} else {
console.log("Hello I'm running!");
intl = setInterval(timers, 5000); // Pass the test reference, not "test()";
}
});
。有时候再生是有意义的,但我不认为它在这里。
{{1}}
答案 1 :(得分:1)
我建议使用setInterval
,因此您不需要继续重新设置超时;保存返回值,并在叠加层关闭时使用clearInterval
:
var interval = setInterval(work, 1000)
close_button.onclick = function() {
clearInterval(interval)
}
正如@Jared所提到的,javascript与Java不一样:)幸运的是......