问题
I have a simple webworker which keeps the current time of timezone using setInterval
setInterval(() => {
userTimezoneTimestamp = userTimezoneTimestamp + 1000
postMessage(userTimezoneTimestamp);
}, 1000);
It works fine until I put my machine on sleep mode. When I restart the machine from sleep mode, the time which I get from this worker is older. How can I restart my web worker only when the machine starts up from sleep mode?
回答1:
There doesn't seem to be any DOM event letting us know about that event.
On my notebook Chrome does fire a non-standard orientationabsolutechange event, but I think not all notebooks have orientation aware hardware and already just Firefox on the same machine doesn't fire it.
But for what you want (an always up to date offset from an API served timestamp), you don't need a WebWorker at all, nor any timer, the computer comes with a good one and not only will it still be up to date after computer sleep, it will even be more precise than your interval which can suffer from time-drift.
All you need is to store the offset you got from your API and the computer's time you received it. Then you just need to get the difference between now and that time of reception and you can easily get your updated offset.
OP noted that they are afraid their users modify their computer's time to an earlier date, thus messing up with Date
's values while the page is running. This can be detected. All it takes is to store the last value, and check if the difference with the current one is negative.
( async () => {
const offset_from_API = await getOffsetFromAPI();
const time_received = Date.now();
let last_time = time_received;
const getUpToDateOffset = () => {
const now = Date.now();
// Anti-Back-Time-Travelling check
// (it's a good idea to poll this method quite often too update `last_time`)
if( now - last_time < 0 ) {
throw new Error( 'cheater detected' );
}
last_time = now;
return offset_from_API + (now - time_received);
};
// to compare we will also use an incrementer
let incremented = offset_from_API;
setInterval( () => {
incremented += 1000;
console.clear();
console.log( 'incremented', incremented.toLocaleString( 'en-US' ) );
console.log( 'difference ', getUpToDateOffset().toLocaleString( 'en-US' ) );
}, 1000 );
} )();
function getOffsetFromAPI() { return 1234567; }
回答2:
setInterval(() => {
/*handle userTimezoneTimestamp stuff every N miliseconds */
}, N);
setInterval(() => {
userTimezoneTimestamp = userTimezoneTimestamp + 1000
postMessage(userTimezoneTimestamp);
}, 1000);
来源:https://stackoverflow.com/questions/60753888/how-to-restart-web-workers-when-computer-restarts-from-sleep-mode