簡體   English   中英

每分鍾呼叫功能

[英]call function on the minute every minute

我寫的每分鍾調用一個函數的代碼,我認為是有缺陷的,因為它有一段時間的好處,但是自頁面加載以來每小時往往會落后大約15秒。 說實話,我無法弄清楚導致滯后的原因,也許是執行功能所需的時間,小的失誤都會累積和累積。 有沒有辦法自動糾正函數內的失誤。 或者也許有人知道在分鍾函數調用上實現更好的方法。 任何幫助或想法非常感謝。 謝謝。

var now = new Date();
var delay = 60 * 1000; // 1 min in msec
var start = delay - (now.getSeconds()) * 1000 + now.getMilliseconds();

setTimeout(function setTimer() {
  onTheMinFunc();
    setTimeout(setTimer, delay);
}, start);     

首先,DOM Timers API不保證准確性。 我引述

此API不保證計時器將按計划運行。 由於CPU負載,其他任務等導致的延遲是預期的。

其次,你執行onTheMinFunc()會導致每一輪延遲(你只在完成時設置超時)。

所以,讓我們說onTheMinFunc需要半秒才能執行 - 你每分鍾都會得到半秒鍾的延遲並且它會累積 - 只需要10分鍾它就會相當滯后。 (注意,函數通常不應超過15ms才能執行以避免明顯滯后)

嘗試:

setInterval(onTheMinFunc, delay);

它仍然不會很准確。 您可以在更短的時間間隔內輪詢並跟蹤日期變量 - 但同樣 - 無法保證。

你可能想要的是setInterval

setInterval(onTheMinFunc, delay);  

因此,使用setTimeout的代碼意味着執行onTheMinFunc所需的時間會在下一個啟動之前添加到您的延遲中,因此隨着時間的推移,這個額外的延遲將會增加。

使用setInterval會更准確,因為延遲是在執行函數的調用之間,而不是僅在函數完成后啟動計時器。

定時器和javascript時間不是很准確,我認為確保函數每隔一段時間執行一次的唯一方法是檢查每秒的秒數

setInterval(function() {
    if ( new Date().getSeconds() === 0 ) onTheMinFunc();
},1000);

小提琴

我想你想要更接近這個:

function setNextMinute() {

    // figure out how much time remains before the end of the current minute
    var d = new Date().getTime()%60000;
    //set a timeout to occur when that expires.
    setTimeout(function () {
    // recalculate a new timeout so that your timer doesn't lag over time.
        doWhateverYouWantToHere();
        // note that calling doWhateverYouWantToHere() will 
        // not offset the next minute, since it is recalculated in setNextMinute()
        setNextMinute();
    },60000-d);
}
setNextMinute();

警告:我沒有徹底測試這個時間。 但它看起來間隔1秒,間隔1分鍾。

這樣做的好處是不會每秒重新計算,也不僅僅是從當前時間開始計時60秒。

以下是對代碼的略微修改:

function everyMinute(fn) {
   arguments[1] && fn();
   var now = new Date();
   var delay = 60 * 1000 - (now.getSeconds()) * 1000 + now.getMilliseconds();
   setTimeout(function(){
     everyMinute(fn, true);
   }, start);
}
everyMinute(onTheMinFunc);

它會重新計算每次等到下一分鍾的毫秒數,以便盡可能准確地達到分鍾的最高點。

目前接受的答案可能有點過分

執行if ( new Date().getSeconds() === 0 ) onTheMinFunc(); 每一秒(永遠)似乎不是一個好主意。

我不會將它與以下命題進行對比,這是沒有必要的。

線索

  1. 使用任何必要的邏輯來計算開始時刻
  2. 開始的那一刻

    1. 使用setInterval重新執行執行
    2. 執行第一個電話

      • 注意 setInterval被稱為ASAP以避免時間過去。

如果你想要那個new Date().getSeconds() === 0

var id = setInterval(function() {
    if ( new Date().getSeconds() === 0 ) {
        setInterval(onTheMinFunc, delay);
        onTheMinFunc();
        clearInterval(id);
    }
},1000);

或者,您可以使用自己的邏輯:

var now = new Date();
var delay = 60 * 1000; // 1 min in msec
var start = delay - (now.getSeconds()) * 1000 + now.getMilliseconds();

setTimeout(function() {
  setInterval(onTheMinFunc, delay);
  onTheMinFunc();
}, start);

請檢查兩個關於jsfiddle的示例

第二個(例B)似乎更准確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM