【问题标题】:Set an interval for every 12 hours设置每 12 小时的间隔
【发布时间】:2017-07-25 12:03:01
【问题描述】:

我需要一个函数来开始运行,然后在中午 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));
        }
    }

但是这并没有按预期工作,并且该函数提前运行,然后每小时运行多次。

【问题讨论】:

  • 谁会让他们的浏览器打开 12 小时以再次运行该功能?
  • 思路是如果用户在11:50访问该站点,该函数需要在12:00再次运行。
  • 更好的问题是:Imagine17 真的等了 12 个小时才知道它是否有效:D
  • 它很容易测试。正如我所说,该函数会提前运行,然后每小时运行多次。
  • 我认为我们遗漏了一些东西。 fetch_datetime() 里面有什么?

标签: javascript jquery vue.js


【解决方案1】:

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

// 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 界面,但会以捆绑大小为代价。

【讨论】:

  • @Imagine17 请注意,我的代码中有错字(第一个 getHours 缺少括号)。
【解决方案2】:

我首先会计算到下一个上午/下午 12 点的距离,在第一次运行后,您可以在每次通话中添加 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。

【讨论】:

    猜你喜欢
    • 2016-08-21
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 2019-05-11
    • 1970-01-01
    • 2012-04-06
    • 2023-04-07
    相关资源
    最近更新 更多