如何每小时调用一次函数
How to call a function every hour?
我正在尝试更新页面上的天气服务信息。信息应每小时更新一次。我究竟如何每小时调用一个函数?
我有点想法,但我不确定如何实际完善它以便它起作用......我想到的是创建一个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)调用一次。
在整点过后的特定分钟重复
这个计数器更通用一些;它允许总是在整点过去的同一分钟(例如,整点过后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 分钟就会进入睡眠状态。
编辑:哎呀,我没有看到"点钟"的东西,所以我编辑了我的答案:
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));
对setIntervalWithDelay
和clearIntervalWithDelay
,可以这样使用:
let descriptor = setIntervalWithDelay(callback, 60 * 60 * 1000, nextHourDelay)
当你完成它时:
clearIntervalWithDelay(descriptor)
这是我对这些函数的实现:
const setIntervalWithDelay = (callback, interval, delay = 0) => {
let descriptor = {}
descriptor.timeoutId = setTimeout(() => {
if(!descriptor.timeoutId){
return
}
descriptor.timeoutId = null
callback()
descriptor.intervalId = setInterval(callback, interval)
}, delay)
return descriptor
}
export const clearIntervalWithDelay = (descriptor) => {
if(!isObject(descriptor) || (!descriptor.timeoutId && !descriptor.intervalId)){
console.warn("clearIntervalWithDelay: Incorrect descriptor. Please pass an object returned by setIntervalWithDelay. Skipping this call.")
return
}
if(descriptor.timeoutId){
clearTimeout(descriptor.timeoutId)
descriptor.timeoutId = null
console.log("clearIntervalWithDelay: stopped during delay.")
}
if(descriptor.intervalId){
clearInterval(descriptor.intervalId)
descriptor.intervalId = null
console.log("clearIntervalWithDelay: stopped during interval repeat.")
}
}
使用 dayjs
获取下一个小时的延迟的一个示例:
let nextHour = dayjs().second(0).millisecond(0).add(1, "hour")
let nextHourDelay = nextHour.diff(dayjs())
- 使用每500ms运行一次的jquery函数是个好主意吗
- Javascript函数,需要每隔30秒递减一次
- 当元素可见时,jQuery滚动函数会触发一次
- 使函数只运行一次(Javascript)
- 如何在Javascript中设置函数在上一次结束时启动
- 运行“;非“;单击另一个函数中的函数仅一次
- 角函数每秒钟增加一次
- JavaScript只有在最后一次被调用时才运行函数
- 如何只使用一次window.onload函数
- 如何每 10 秒调用一次 JS 函数,然后以角度激活一个函数
- 节点 js 在启动时调用函数一次
- 有人可以帮助我调试带有addClass和removeClass函数的“每个会话一次”cookie吗?
- 如何在 window.setInterval 中每分钟运行一次 getJSON 函数
- 一次将多个对象传递给函数参数
- 就绪函数上的指令只能执行一次
- 一段时间后调用函数,但只调用一次
- 如何加载一个html页面并在其中只需单击一次即可运行函数
- Javascript只使用setInterval()调用一个子函数一次
- 元素在JavaScript函数中只更改过一次
- 函数只更改一次内容