我正在制作个人使用的chrome扩展程序,它将以递归方式调用setTimeout。我想确保在任何情况下此扩展都不会意外地产生多个setTimeouts链。
我已经做到这一点,当我点击浏览器操作时,它会调用clearTimeout。但是,我担心当我重新加载扩展时,旧的超时链可以继续吗?并且可能还有其他我不想的场景。是否有一种经过验证的方法来防止意外创建多个超时链?
看起来无法枚举有效的javascript计时器:Viewing all the timouts/intervals in javascript?
答案 0 :(得分:1)
我之前解决过类似的案例:
var timer;
function foo(){
if(!timer)
timer = setTimeout(function (){
//should print once every second only
console.log(new Date());
timer = null;
foo();
}, 1000)
}
foo();
foo();
由于javascript在处理下一个事件之前将同步代码运行完成,因此这是安全的。
答案 1 :(得分:1)
我的冲动一直是使用clearTimeout
来抑制竞争超时,但我也喜欢Johan Gov的回答,特别是在推广时:
var setOneTimeout = (function() {
var timer
return function(f, timeout) {
if (!timer) {
timer = setTimeout(function() {
timer = null
f()
}, timeout)
}
}
})()
setOneTimeout(function() { console.log('foo') }, 500)
setOneTimeout(function() { console.log('bar') }, 500)
/* outputs "foo", only. */
或者,如果您有多个类别的超时,并且只希望每个类别中有一个“正在运行”超时:
var setNamedTimeout = (function() {
var timer = {}
return function(name, f, timeout) {
if (!timer[name]) {
timer[name] = setTimeout(function() {
timer[name] = null
f()
}, timeout)
}
}
})()
setNamedTimeout('foo', function() { console.log('foo') }, 500)
setNamedTimeout('bar', function() { console.log('bar') }, 500)
setNamedTimeout('bar', function() { console.log('bar') }, 500)
setNamedTimeout('bar', function() { console.log('bar') }, 500)
setNamedTimeout('bar', function() { console.log('bar') }, 500)
setNamedTimeout('foo', function() { console.log('foo') }, 500)
/* outputs only one instance of "foo" and "bar" */