【问题标题】: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 线程可能正忙于在那个精确的时刻做其他事情(它甚至可能被占用几秒钟)。
除此之外,还有设备同步问题。选项是:
-
您同时向两台设备发送的某种同步事件。您将运行代码以响应从服务器接收到的同步事件。这自然会受到网络延迟的影响,它需要服务器发送事件(可能通过 Web 套接字),并且受上述关于 JavaScript 线程繁忙的警告的影响。
-
依赖于同步到完全相同时间源的设备(例如,它们可能都使用 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) 的毫秒数,并将回调安排在这么多毫秒之后。