繁体   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