每分钟调用一次函数
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 分钟后它会滞后很多。(注意,函数通常不应超过 15 毫秒才能执行,以避免明显的延迟(
尝试:
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();
似乎不是一个好主意。
我不会根据以下命题进行基准测试,没有必要。
蛛丝马迹
- 使用任何必要的逻辑来计算开始时刻。
-
在开始时刻
- 使用
setInterval
重新执行 -
执行第一个调用
-
请注意,
setInterval
称为"尽快"以避免时间流逝。
-
请注意,
- 使用
如果你想要那个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(似乎更准确。
- 使用每500ms运行一次的jquery函数是个好主意吗
- Javascript函数,需要每隔30秒递减一次
- 当元素可见时,jQuery滚动函数会触发一次
- 使函数只运行一次(Javascript)
- 如何在Javascript中设置函数在上一次结束时启动
- 运行“;非“;单击另一个函数中的函数仅一次
- 角函数每秒钟增加一次
- JavaScript只有在最后一次被调用时才运行函数
- 如何只使用一次window.onload函数
- 如何每 10 秒调用一次 JS 函数,然后以角度激活一个函数
- 节点 js 在启动时调用函数一次
- 有人可以帮助我调试带有addClass和removeClass函数的“每个会话一次”cookie吗?
- 如何在 window.setInterval 中每分钟运行一次 getJSON 函数
- 一次将多个对象传递给函数参数
- 就绪函数上的指令只能执行一次
- 一段时间后调用函数,但只调用一次
- 如何加载一个html页面并在其中只需单击一次即可运行函数
- Javascript只使用setInterval()调用一个子函数一次
- 元素在JavaScript函数中只更改过一次
- 函数只更改一次内容