1

I have an application that calculates multiple differences bewteen 2 points of times troughout the whole day. I use a countdown timer to show the difference bewteen those 2 points. Whenever the countdown reaches 00.00.00 the app will then start with the countdown of the next calculation between 2 points of times.

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

This is what I have so far. I have the WebWorker implemented but it seems there is still a delay whenever I switch tabs. 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. Anyone can help me in the right direction?

SC92
  • 161
  • 13

1 Answers1

-1

This may be due to the inaccuracy of setTimeout: What is the reason JavaScript setTimeout is so inaccurate?

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.

jsdeveloper
  • 3,945
  • 1
  • 15
  • 14