2011-04-27 67 views
15

有問題。如果我使用的setInterval以這種方式:javascript setInterval

setInterval('doSome();',60000); 

我是安全的doSome()功能是每60秒發送一次,即使我改變瀏覽器的標籤?

+6

你不應該傳遞一個字符串'setInterval'但功能:'的setInterval(doSome,60000);'或者如果你需要的參數等:'的setInterval(函數(){doSome(12345);}, 60000);' – ThiefMaster 2011-04-27 08:58:06

+0

當然。我建議你把它作爲setInterval(doSome,60000)來代替,這樣更有效率。 – gpilotino 2011-04-27 08:59:33

+0

傳遞給'setInterval'的字符串很好。區別在於他們如何評估以及從什麼範圍進行評估。 – 2011-04-27 09:13:33

回答

1

如果setInterval()函數的選項卡保持打開狀態,那麼該函數將每60秒執行一次,即使您切換到或打開其他選項卡。

0

是,瀏覽器的焦點是無關緊要的。

但是,您不應使用setInterval的字符串參數。請使用該功能的參考代替:

setInterval(doSome, 60000); 
+0

傳遞給'setInterval'的字符串很好。區別在於他們如何評估以及從什麼範圍進行評估。 – 2011-04-27 09:12:18

+0

@Delan速度和語法突出顯示,以及需要執行諸如轉義引號之類的蠢事。將字符串傳遞給'setInterval'並不是錯誤的*,本身就是沒有意義的。 – lonesomeday 2011-04-27 10:30:36

+0

這是真的,我同意你的看法。 – 2011-04-27 10:41:48

0

不,您無法保證確切的時間安全。 JS是基於事件(和單一三合一)的,所以事件不會在恰當的時刻觸發,特別是當你的頁面上同時運行其他代碼時。

事件將在設定的時間值附近觸發,但不是精確的毫秒。即使當時沒有其他事件正在運行,錯誤可能是幾十毫秒。這可能是一個問題,例如,如果您有一個長時間運行的流程,其中時間安排非常重要。如果你這樣做,你需要偶爾同步一個時鐘。

0

是的,只要頁面處於打開狀態,無論切換標籤頁還是瀏覽器被最小化,都會被調用。

但是確保你傳遞給函數不是字符串給setInterval

應該>

setInterval(doSome, 60000)

+0

傳遞給'setInterval'的字符串很好。區別在於他們如何評估以及從什麼範圍進行評估。 – 2011-04-27 09:13:09

+0

謝謝,我不知道。 – neebz 2011-04-27 09:24:36

28

將字符串傳遞到setInterval是好的,而且是兩種方式,以一個使用setInterval,另一個是傳遞一個函數指針。這與其他答案狀態沒有任何關係,但並不像其他答案那樣有效(因爲必須重新編寫代碼),而且您的目的也不是必需的。無論

setInterval('doSome();', 60000); // this runs doSome from the global scope 
           // in the global scope 

setInterval(doSome, 60000);  // this runs doSome from the local scope 
           // in the global scope 

是正確的,但他們有一個含義略有不同。如果doSome對於某個非全局作用域是本地的,則在相同作用域內調用後者將以60000ms間隔運行本地doSome。調用前面的代碼將始終在全局範圍內查找doSome,並且如果全局範圍中沒有doSome函數,將會失敗。

功能將可靠地被觸發,而不考慮標籤的焦點,在至少 60000毫秒間隔,但通常稍微由於開銷和延遲。

所有瀏覽器將間隔值限制在至少一定的值以避免間隔過於頻繁(我認爲這是最小值10ms或4ms,或者我不能完全記住)。請注意,有些瀏覽器(即將推出的Firefox 5是一款,但也有可能是我不知道的其他瀏覽器)會進一步將setInterval嚴重限制爲例如1/4。如果選項卡未聚焦,則爲1000毫秒。 (Reference

+0

另一個區別 - 在第一個版本中,您可以更改全局變量'doSome'的值,並且間隔將開始調用新函數。在第二個版本中,你不能這樣做。 – 2011-12-15 09:31:24

2

不,在事件循環被清除之前,時間間隔不能執行,所以如果你做了例如setInterval(func, 1000); for(;;)那麼間隔永遠不會運行。如果其他瀏覽器選項卡在同一個線程中運行(因爲它們的確無處不在(?)除了鉻,那麼同樣適用,如果這些標籤堵塞事件循環。)

但對於大如60000它是在一個區間至少很有可能在合理的時間內調用func。但沒有保證。

0

關於「準確的時間安全性」:以下代碼以RefreshInterval毫秒的間隔開始UpdateAll,每秒調整一次,以便在第二秒的開始時每秒發生一次啓動。計算機的有限速度會稍稍延遲,但錯誤不會累積。

function StartAtEachSecond() 
{ 
    var OneSecond = 1000; // milliseconds 
    var MinInteral = 50; // milliseconds, estimated safe interval 
    var StartTime = OneSecond - (new Date()).getMilliseconds(); // Time until next second starts. 
    if (StartTime < MinInteral) StartTime += OneSecond 
    window.setTimeout (StartAtEachSecond, StartTime + MinInteral); // To set up the second after the next. 
    for (var Delay = 0.0; Delay < OneSecond - MinInteral; Delay += RefreshInterval) 
    { 
     window.setTimeout (UpdateAll, StartTime + Delay); // Runs during the next second. 
    } 
}