【问题标题】:Interval synced to Time与时间同步的间隔
【发布时间】:2021-04-21 09:44:23
【问题描述】:

我想在一个区间内执行一个函数。是的,我可以使用 setInterval,但我需要将时间间隔同步到时间戳或其他东西。

就像我想在两个不同的设备上执行间隔,如果可能的话,它们应该在完全相同的秒甚至毫秒内运行。但是,如果我使用 setInterval 方法,这些时间间隔会根据我在脚本中加注星标的时间而有所不同。

我已经尝试过了,但它有点奇怪。

setInterval(() => {
        if (new Date().getTime() % 1000 * 10 == 0) {
            console.log(new Date().toLocaleTimeString())
        }
    }, 1);

【问题讨论】:

    标签: javascript time synchronization setinterval


    【解决方案1】:

    就像我想在两个不同的设备上执行间隔,如果可能的话,它们应该在完全相同的秒甚至毫秒内运行。

    无法保证您可以做到这一点,尤其是因为其中一台设备上的 JavaScript 线程可能正忙于在那个精确的时刻做其他事情(它甚至可能被占用几秒钟)。

    除此之外,还有设备同步问题。选项是:

    1. 您同时向两台设备发送的某种同步事件。您将运行代码以响应从服务器接收到的同步事件。这自然会受到网络延迟的影响,它需要服务器发送事件(可能通过 Web 套接字),并且受上述关于 JavaScript 线程繁忙的警告的影响。

    2. 依赖于同步到完全相同时间源的设备(例如,它们可能都使用 NIST 时间服务器或类似设备)。如果您知道他们的时间对于您的目的已充分同步,您可以安排您的计时器在精确的时刻触发,如下所示:

      // Fire at exactly 14:30 GMT on 2021-04-21
      const target = new Date(Date.UTC(2021, 3, 21, 14, 30)); // 3 = April, starts with 0 = Jan
      const delay = Date.now() - target;
      if (delay < 0) {
          // It's already later than that
      } else {
          setTimeout(() => {
              // Your code here
          }, delay);
      }
      

      但是,同样,如果 JavaScript 线程在那个精确的时刻很忙,计时器回调将在线程空闲时运行。

      上面的代码安排了一个单个事件,但是如果您需要一个重复的事件,您可以执行相同的基本逻辑:确定您希望下一次回调发生的日期/时间,了解如何从现在到那时 (Date.now() - target) 的毫秒数,并将回调安排在这么多毫秒之后。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      • 2020-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多