2015-10-16 29 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" */