2015-10-16 73 views
1

我正在做一个个人使用的铬扩展,将递归调用setTimeout。我想确保在任何情况下,这个扩展都不会意外产生多个setTimeouts链。如何确保我只有一个递归setTimeouts链一次运行?

我已经做到了,当我点击浏览器动作时,它会调用clearTimeout。但是,我担心什么时候重新加载扩展,老的超时链会继续?而且可能还有其他场景我没有想到。有没有一种可靠而真实的方法来防止意外创建多个超时链?

它看起来像有没有办法一一列举活跃的JavaScript计时器:

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代码同步完成处理前:Viewing all the timouts/intervals in javascript?

+0

你能添加一些代码吗?因为它不完全清楚你怎么“递归调用”setTimeout。在任何情况下,如果你在后台页面脚本中执行它,那么所有定时器将在重新加载时被销毁。除非您还重新加载网页,否则只有注入内容脚本才能存活。另外,我建议使用'chrome.alarms' API。 – wOxxOm

回答

1

我之前解决了类似的情况下,这样的下一个事件是安全的。

1

我的冲动会一直使用clearTimeout压制竞争超时,但我喜欢约翰州长的回答为好,广义尤其是当:

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" */