设置间隔为每 12 小时

Set an interval for every 12 hours

我需要一个函数来 运行,然后在中午 12 点和凌晨 12 点重新运行。如果有任何影响,我正在使用 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));
        }
    }

然而,这并没有像预期的那样工作,并且函数提前了 运行,然后在整点多次 运行。

这是一个非常简单的函数,可以做你想做的事。它应该适合您的用例(几分钟后刷新),但不要指望它在浏览器更改时具有很强的弹性。

// 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');
});

如果您正在寻找更强大的解决方案,您还可以使用 later.js,它声称可以在浏览器上运行并提供功能齐全的 cron 界面,但要以捆绑包大小为代价。

我首先会计算到下一个 12 am/pm 的距离,在第一个 运行 之后,您可以在每次通话中增加 12 小时或创建一个间隔。

要获得到第一个 运行 的距离,您可以使用 Date.now 的差异和到 运行 的时刻:

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

在此之后将所有小于小时的单位设置为零。

初次通话后: setInterval(this.fetch_datetime, 12 * 60 * 60 * 1e3)

还有一个vue插件,它提供了间隔和回调的帮助https://www.npmjs.com/package/vue-interval

您还应该记住,setTimeout 和 setInterval 并不是绝对正确的。它们可能会提前或延迟几毫秒被触发。所以计算到下一个执行时刻的差异可以触发函数double。