简体   繁体   English

将setTimeout与Web Worker一起使用时的React Hooks延迟

[英]React Hooks delay when using setTimeout with Web Worker

I have an application that calculates multiple differences bewteen 2 points of times troughout the whole day. 我有一个应用程序,可以计算整天经过2个时间点的多个差异。 I use a countdown timer to show the difference bewteen those 2 points. 我使用倒数计时器来显示那2点之间的差异。 Whenever the countdown reaches 00.00.00 the app will then start with the countdown of the next calculation between 2 points of times. 每当倒计时达到00.00.00时,应用程序就会从2个时间点之间的下一次计算倒计时开始。

So I need a countdown timer that is running constantly, even if the tab is inactive. 因此,即使选项卡处于非活动状态,我也需要一个持续运行的倒计时计时器。 I found out that when the current tab is inactive the setTimeout will have a small delay 我发现当当前选项卡处于非活动状态时,setTimeout将有一个小的延迟

This is what I have so far. 这就是我到目前为止所拥有的。 I have the WebWorker implemented but it seems there is still a delay whenever I switch tabs. 我已经实现了WebWorker,但每次切换选项卡时似乎仍然存在延迟。 I am logging the timer each second so I tested it with opening the console in a separate window and switching tabs. 我每秒记录一次计时器,因此我通过在单独的窗口中打开控制台并切换选项卡来对其进行测试。

This is what I have so far 这就是我到目前为止所拥有的

import worker    from './worker.js';
import WebWorker from './WebWorker';
const useSetInterval = ({ prayerTime }) => {
    // SET THE STATE OF SECONDS, MINUTES AND HOURS
    const [seconds, setSeconds] = useState(60 - Number(moment().format('ss')));
    const [minutes, setMinutes] = useState(prayerTime.minutes);
    const [hours, setHours]     = useState(prayerTime.hours);

    useEffect(() => {
        const w = new WebWorker(worker);
        w.postMessage({ seconds, minutes, hours }); 

        w.addEventListener('message', e => {
            const { newSeconds, newMinutes, newHours } = e.data;
            setSeconds((newSeconds < 0) ? 59 : newSeconds);
            if (newSeconds < 0)
            {
                setMinutes((newMinutes < 0) ? 59 : newMinutes);
                if (newMinutes < 0) setHours((newHours < 0) ? "Refresh" : newHours); 
            }
        });     

        return () => w.terminate();
    }, [seconds, minutes, hours]);  

    return { seconds, minutes, hours };
};

// Webworker.js
export default class WebWorker {
    constructor(worker) {
        const code = worker.toString();
        const blob = new Blob(['('+code+')()']);
        return new Worker(URL.createObjectURL(blob));
    }
}

// worker.js
export default () => {
    self.addEventListener( "message", (e) => {
        if (!e) return;

        const { seconds, minutes, hours } = e.data;

        setTimeout(() => {
            const newSeconds = seconds - 1;
            const newMinutes = (newSeconds < 0) ? minutes - 1 : minutes;
            const newHours   = (newMinutes < 0) ? hours - 1 : hours;

            postMessage({ newSeconds, newMinutes, newHours });
        }, 1000);
    });
};

I have the settimeout at 1000ms, which is 1 second, and I've read when the tab is inactive the timer is delayed to 1000ms, but there still is a delay. 我将settimeout设置为1000ms,这是1秒,并且在选项卡处于非活动状态时,我已经读到计时器延迟到1000ms,但是仍然存在延迟。 Anyone can help me in the right direction? 有人可以在正确的方向帮助我吗?

This may be due to the inaccuracy of setTimeout: What is the reason JavaScript setTimeout is so inaccurate? 这可能是由于setTimeout的不准确性所致: JavaScript setTimeout如此不准确的原因是什么?

When you call setTimeout, the function is added to the Event Table and gets executed after the specified time and then when the Event Loop is free . 当您调用setTimeout时,该函数将添加到事件表中,并在指定时间后以及事件循环空闲时执行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM