倒计时,一般来说
通常,倒数计时器是通过选择计时器将达到零的到期时间来定义的。相对倒计时计时器将使用基于当前时间的计算来定义该到期时间。换句话说,要为“从现在起 10 秒”设置一个计时器,其中 now 被定义为用户单击 start 按钮的时刻,可以使用代码像这样:
// In the start button's click handler
due = Date.now() + 120000 // 120000 is 2 minutes (120 s) expressed in milliseconds
当您单击按钮时,这会被评估。如果您再次单击该按钮,则将重新计算到期时间,并且到期时间将移动到您单击该按钮后 10 秒后的某个时刻。也就是说,程序会再次评估Date.now(),并据此选择新的到期时间。
现在要计算在给定时刻剩余的时间,您可以使用以下计算:
remaining = due - Date.now()
// `remaining` contains number of milliseconds remaining until our countdown is due
在计时器到期之前,这将是一个正数,如果在计时器到期之后评估,则为负数。而且,如果你真的很幸运,你可能会在它到期的那一刻抓住它,而remaining 正好为零。
通常,倒数计时器会定期更新(更改其显示的值)至少每秒一次,尽管频率可能更高(可能显示剩余的十分之一秒,甚至毫秒)或可能频率较低(您可以选择每分钟仅更新一次显示)。
要更新显示,您可以在客户端中使用 JavaScript 间隔计时器。此计时器的频率仅控制您想要更新显示的频率,与它的到期时间或显示剩余时间的精度无关(即显示“剩余 2 分钟”或“2:00剩余”或“2:00.000”剩余)为了获得漂亮、精确的显示,您可以每秒更新 60 次(大约是典型显示器的刷新率),或者如果您只显示几秒的精度,则每次更新 10 次第二个可能就足够了,具体取决于应用程序。
例子:
setInterval(() => {
display(`${due - Date.now()} ms remaining`);
}, updateInterval);
display 可能只是 console.log,或者是更改 DOM 元素文本的代码,也可能是 React setState。取决于您的应用程序。 updateInterval 可能是 250,每秒更新 4 次。
真实的故事:我有一个纸质挂历,但我不会在午夜时分翻月页。实际上,有时我直到每月的第二天或第三天才翻转它,但我通常每两三天“投票”一次,看看是否需要更新。我没有设置闹钟在午夜叫醒我只是为了改变我的日历。一般来说,每天检查一次对我来说就足够了。倒数计时器的工作方式相同。
同步
要让两个倒数计时器同步,它们必须都基于相同的到期时间。并且两者都应该足够频繁地更新,以至于您不会注意到由于显示陈旧而导致的任何差异。
如果您在同一台计算机上有两个浏览器选项卡需要同步,那么只需告诉两个选项卡中的应用程序相同的到期时间就足够了。每个选项卡都可以通过Date.now() 访问相同的系统时间。因此,每个人都可以通过计算due - Date.now() 来显示距离到期时间还剩多少时间。
至于您的 React 倒数计时器,我确信有一种方法可以将到期时间设置为 JavaScript 日期。只需确保服务器向两个选项卡发送相同的到期时间,并且每个选项卡何时加载并启动倒数计时器都无关紧要,因为客户端不会为倒计时的本地显示分配到期日期的值基于Date.now()的计时器,它将从服务器显式接收到期时间。
关键是由服务器提供计时器的到期时间。注定要同时达到 0 的两个倒数计时器实际上是相同的逻辑。如果它们以合理的频率保持更新,则显示将显示为合理同步。
注意使用 UTC 将日期传输到客户端,这样就不会因服务器和客户端之间的时区差异而出现问题。
如果您在编程 React 倒数计时器以将其设置为特定的截止日期时需要帮助,那么您应该披露您正在使用的库/组件并显示您如何设置计时器的代码。