16

我正在尝试从我的页面上的气象服务更新信息。信息应该每小时更新一次。我究竟如何去每小时调用一个函数?

我有一个想法,但我不确定如何实际改进它以便它工作......我想到的是创建一个 if 语句,例如:(伪代码)

//get the mins of the current time
var mins = datetime.mins();    

if(mins == "00"){
    function();
 }
4

6 回答 6

26

您想查看setIntervalhttps ://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval

很难说出你试图用你的代码调用什么,但它会是以下形式的东西:

function callEveryHour() {
    setInterval(yourFunction, 1000 * 60 * 60);
}

如果您想要每小时一次,请尝试以下操作:

var nextDate = new Date();
if (nextDate.getMinutes() === 0) { // You can check for seconds here too
    callEveryHour()
} else {
    nextDate.setHours(nextDate.getHours() + 1);
    nextDate.setMinutes(0);
    nextDate.setSeconds(0);// I wouldn't do milliseconds too ;)

    var difference = nextDate - new Date();
    setTimeout(callEveryHour, difference);
}

现在,这个实现检查一次时间,设置延迟(或立即调用函数),然后依靠 setInterval 来跟踪。另一种方法可能是每 x 秒/分钟轮询一次时间,然后.getMinutes() == 0改为触发它(类似于 if 语句的第一部分),这可能会牺牲(边缘)性能以获得(边缘)准确性。根据您的确切需求,我会使用这两种解决方案。

于 2013-11-07T21:52:01.403 回答
12

这是应该工作的(JSFiddle):

function tick() {
  //get the mins of the current time
  var mins = new Date().getMinutes();
  if (mins == "00") {
    alert('Do stuff');
  }
  console.log('Tick ' + mins);
}

setInterval(tick, 1000);

于 2013-11-07T21:56:57.433 回答
7

你可能想要的是这样的:

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

setTimeout(function doSomething() {
   // do the operation
   // ... your code here...

   // schedule the next tick
   setTimeout(doSomething, delay);
}, start);

因此,基本上用户第一次获得访问权限时,您需要知道到下一个“小时”的延迟(以毫秒为单位)是多少。因此,如果用户在 8:54(56 秒和 123 毫秒)访问该页面,您必须在大约 3 分钟后安排第一次执行:在第一次执行完成后,您可以每隔“小时”调用一次( 60 * 60 * 1000)。

于 2013-11-07T22:05:28.103 回答
1

编辑:哎呀,我没有看到“点”的东西,所以我编辑了我的答案:

var last_execution = new Date().getTime();
function doSomething(force){
  var current_time = new Date().getTime();
  if (force || (current_time.getMinutes() == 0)
  {
    last_execution = current_time;
    // something
    // ...
  }
  setTimeout(doSomething(false), 1000);
}
// force the first time
doSomething(true); 
于 2013-11-07T21:54:57.257 回答
0
// ... call your func now
let intervalId;
let timeoutId = setTimeout(() => {
  // ... call your func on end of current hour
  intervalId = setInterval(() => {
     // ... call your func on end of each next hours
  }, 3600000);
}, ((60 − moment().minutes()) × 60 × 1000) - (moment().second() * 1000));
于 2019-11-28T22:46:01.053 回答
0

在一小时后的特定分钟重复

这个计数器更通用一些;它允许始终在整点后的同一分钟(例如整点后 37 分钟)重复执行任务,并且精度高达毫秒。

此计时器的精度源自其递归。在每次递归时,都会重新计算到下一分钟的毫秒时间。这可以防止长时间滞后。

%符号是指模运算符

function minuteCount(minutesAfterHour) {

    const now          = new Date();
    const hours        = now.getHours();
    const minutes      = now.getMinutes();
    const seconds      = now.getSeconds();
    const milliseconds = now.getMilliseconds();

    waitUntilNextMinute = setTimeout(minuteCount, 60000 - seconds * 1000 - milliseconds);

    if(minutes % 60 === minutesAfterHour) {
        doSomethingHourly();
    }

}

minuteCount(37);

最后,定时器最好远离主线程。它们最好在web worker中运行,正如这里解释的那样。这与桌面浏览器中未聚焦的选项卡完美配合。

但是,Android 版 Chrome 上的专用网络工作者在将主客户端移至后台后约 5 分钟进入睡眠状态。

于 2021-04-01T05:37:13.817 回答