2010-10-06 117 views
4

是否有無論如何在瀏覽器中創建一個變速計時器,它將給所有操作系統和瀏覽器提供完全相同的結果?如果我想每個用戶每分鐘140次跳動,無論他們的電腦速度如何。基於Web的計時器

我一直在使用javascript setTimeout()和setInterval(),但我認爲它們依賴於計算機的速度和程序中的代碼量。 如何將系統時鐘併入瀏覽器?還是其他想法?

+0

你有任何引用或測試來支持_setTimeout_不準確的說法嗎?它總是爲我工作(雖然我沒有驗證它到每毫秒)。 – 2010-10-06 02:06:21

回答

6

你必須在你的解決方案中使用setTimeoutsetInterval,但是這將是不準確的,原因如下:

  1. 瀏覽器都有一個最小超時,這不是0毫秒。跨瀏覽器的最小值約爲14毫秒。
  2. 定時器不精確。它們代表排隊時間,而不是執行時間。如果在你的定時器觸發時別的東西正在執行,你的代碼會被推到一個隊列中等待,並且可能直到很晚纔會真正執行。

您可能打算使用setTimeout以及手動跟蹤當前時間(使用Date)來執行您的程序。對於你來說,嘗試這樣的事情:

function someAction(delta) { 
    // ... 
} 

function beat() { 
    var currentTime = +new Date; 
    var delta = currentTime - pastTime; 

    if (delta > 430) { // 430ms ~ 140bpm 
    pastTime = currentTime; 
    someAction(); 
    } 

    setTimeout(beat, 107); // 4x resolution 
} 

var pastTime = +new Date; 
beat(); 

這應該接近每分鐘140次,使用更高的分辨率,以避免更大的延遲。儘管這只是一個示例,但您可能需要更多地努力才能使其在應用程序中以最佳方式運行。

+0

(來自@gravityboy) 謝謝本,這是一個很好的答案。如果它超過閾值數,它會執行一個超時4次然後beat()只會調用someaction(),是正確的?如果它在430的閾值之前被稱爲幾毫秒,會發生什麼?那麼在再次等待107次超時之前,它不會再有機會開火? 您認爲setTimeout中可以使用的最小數字是什麼? – bcherry 2010-10-06 20:26:01

+0

(from @gravityboy繼續) 另外你怎麼看只是沒有setimeout循環,只是使用... var currentTime = + new Date; var delta = currentTime - pastTime; 它會運行並檢查計算機允許的速度。字面上數百次,然後在增量變差時調用該函數。 這是一個失控的循環? p.s.我認爲= +新日期是一個錯字,但不是。它以毫秒顯示日期?我甚至無法在任何地方找到記錄。 – bcherry 2010-10-06 20:26:36

+0

是的,你是正確的,這可能導致100ms的延遲。這只是應用程序響應和計時器準確性方面的折衷。如果你使用0ms設置'setTimeout',它將執行瀏覽器允許的最快速度(在某些情況下約14ms),這將提供最好的分辨率,從而達到最高的準確度。但是,這會以犧牲其他應用程序爲代價。對於簡單的事情來說,這應該很好,但對於複雜的應用程序來說,這可能效果不佳。 – bcherry 2010-10-06 20:28:51

0

你可以使用的最好的是setInterval()或嘗試從Date()派生的東西。

請注意,時間並不準確,我認爲是因爲JavaScript的單線程本質。

0

setTimeout()setInterval()功能幾乎是最好的你會得到。這些函數的超時參數以毫秒爲單位指定,取決於運行瀏覽器的計算機的總體速度,其值爲而不是

但是,這些函數當然不是硬實時函數,並且如果瀏覽器在您的超時或時間間隔到期時忙於執行其他操作,可能會稍微延遲,然後實際調用回調函數。