如何在多个浏览器标签中同步倒数计时器?

时间:2018-10-15 08:55:20

标签: reactjs timer redux browser-tab

我正在React上开发一个应用程序,其中以倒数计时器为主要组件(同时页面上可以有10-20个计时器)。从服务器上我得到:计时器应该运行多长时间,还剩多少秒。然后,我每秒重新计算还剩多少。源数据存储在redux中,并以组件本地状态进行计算。

这些计时器应为每个用户显示相同的值。

问题是,当我在浏览器中复制选项卡时,不会发生api请求,分别将新选项卡中的计时器回滚到旧状态。 在Redux中每秒更新数据似乎不是最好的选择,但是我还没有看到其他人。

1 个答案:

答案 0 :(得分:0)

您说服务器以秒为单位发送剩余时间。因此,您可以在客户端计算倒数计时应在客户端时间结束的时间。您可以将其存储在本地存储中。当打开一个新选项卡时,您可以使用该值初始化计时器。

由于所有选项卡共享相同(可能是错误的)客户端时间,因此不需要客户端时间正确或与服务器时间同步。您只对当前客户端时间与为正确初始化计时器而保存的客户端时间之间的秒数差异感兴趣。

一种计算方法大致如下:

// when receiving the remaining seconds in the first tab

const onReceivedRemaining = (remaining) => {
    const now = new Date(); // current client time
    now.setSeconds(now.getSeconds() + remaining); // timer end in client time

    localStorage.set('elapsing', JSON.stringify(now));
}

// when initializing the timer in a second tab

const getInitial = () => {
    const elapsing_string = localStorage.get('elapsing');
    if (!elapsing_string) return null;

    const now = new Date();
    const elapsing = Date.parse(elapsing_string);
    return (elapsing - now) / 1000; // remaining time in seconds
}