我正在尝试从我的页面上的气象服务更新信息。信息应该每小时更新一次。我究竟如何去每小时调用一个函数?
我有一个想法,但我不确定如何实际改进它以便它工作......我想到的是创建一个 if 语句,例如:(伪代码)
//get the mins of the current time
var mins = datetime.mins();
if(mins == "00"){
function();
}
我正在尝试从我的页面上的气象服务更新信息。信息应该每小时更新一次。我究竟如何去每小时调用一个函数?
我有一个想法,但我不确定如何实际改进它以便它工作......我想到的是创建一个 if 语句,例如:(伪代码)
//get the mins of the current time
var mins = datetime.mins();
if(mins == "00"){
function();
}
您想查看setInterval
:https ://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 语句的第一部分),这可能会牺牲(边缘)性能以获得(边缘)准确性。根据您的确切需求,我会使用这两种解决方案。
这是应该工作的(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);
你可能想要的是这样的:
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)。
编辑:哎呀,我没有看到“点”的东西,所以我编辑了我的答案:
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);
// ... 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));
这个计数器更通用一些;它允许始终在整点后的同一分钟(例如整点后 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 分钟进入睡眠状态。