简体   繁体   English

设置间隔为每12小时

[英]Set an interval for every 12 hours

I need a function to run initially and then to rerun at 12pm and 12am. 我需要一个函数首先运行,然后在12pm和12am重新运行。 I'm using VueJS if that has any influence. 如果有影响,我正在使用VueJS。

fetch_datetime()
{
    axios.get('/api/core/datetime').then((response) => {
        this.datetime = response.data;
        this.set_interval();
    });
},

set_interval()
{
    var current_date = new Date();
    var hours = current_date.getHours();
    var minutes = current_date.getMinutes();
    var seconds = current_date.getSeconds();
    if(hours == 12 && minutes == 0 && seconds == 0 || hours == 0 && minutes == 0 && seconds == 0)
    {
        this.fetch_datetime();
    } else
    {
        if(hours >= 12)
        {
            setTimeout(this.fetch_datetime, (1000 * (60 - seconds) * (60 - minutes)) + (1000 * 60 * (24 - hours - 1) * 60));
        } else
        {
            setTimeout(this.fetch_datetime, (1000 * (60 - seconds) * (60 - minutes)) + (1000 * 60 * (12 - hours - 1) * 60));
        }
    }

However this isn't working as expected and the function runs early and then runs multiple times on the hour. 但是,这不能按预期方式工作,该功能提早运行,然后在一小时内多次运行。

Here is a very simple function that can do what you want. 这是一个非常简单的功能,可以执行您想要的操作。 It should fit your use case (refresh after some minutes) but don't expect it to be very resilient on browser changes. 它应该适合您的用例(几分钟后刷新),但是不要期望它在浏览器更改时具有很好的适应性。

 // Takes an array of hours as number and a function to execute function executeOnHours(hours, callback) { callback(); // First, execute once let now = new Date(); const hoursWithToogle = hours.map(h => { return { value: h, executedToday: now.getHours() === h // Don't run now if already on the given hour } }); setInterval(() => { now = new Date(); const triggers = hoursWithToogle.filter(h => { if (!h.executedToday && h.value === now.getHours()) { return h.executedToday = true; } else if (h.value !== now.getHours()) { h.executedToday = false; // Clean the boolean on the next hour } }); if (triggers.length) callback(); // Trigger the action if some hours match }, 30000); // Fix a precision for the check, here 30s } executeOnHours([0, 12], function() { console.log('Something is done'); }); 

If you are looking for a far more robust solution, you can also use later.js , that claims to work on browser and offer a full featured cron interface, at the cost of bundle size. 如果您正在寻找更强大的解决方案,则还可以使用Later.js ,它声称可以在浏览器上工作并提供功能齐全的cron界面,但以捆绑包大小为代价。

I would at first calculate the distance to the next 12 am/pm and after the first run you can add 12 hours in every call or create an interval. 首先,我要计算到下一个12 am / pm的距离,第一次运行后,您可以在每个通话中增加12小时或创建一个间隔。

To get the distance to the first run you can use difference of Date.now and the moment to run: 要获得到第一次运行的距离,可以使用Date.now和运行时刻的Date.now

var n = new Date()
if(n.getHours()>=12){
  n.setHours(24);
}else{
  n.setHours(12);  
}

After this set all smaller units than hour to zero. 此后,将所有小于小时的单位设置为零。

After initial call: setInterval(this.fetch_datetime, 12 * 60 * 60 * 1e3) 初始调用后: setInterval(this.fetch_datetime, 12 * 60 * 60 * 1e3)

There is also a vue plugin which provides help for intervals and callbacks https://www.npmjs.com/package/vue-interval 还有一个vue插件,可为间隔和回调提供帮助https://www.npmjs.com/package/vue-interval

You should also have in mind that setTimeout and setInterval are not absolutely correct. 您还应该记住,setTimeout和setInterval并非绝对正确。 They may get triggered a few millisecounds to early or to late. 他们可能会在早期或晚期触发几毫秒的信号。 So calculating the difference to the next execution moment can trigger the function double. 因此,计算到下一个执行时刻的差可以触发函数加倍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM