我使用chrome.alarm
在扩展图标上显示倒计时,它每秒更新一次'ish。我面临的问题是,如果我将系统的时间向前更改(手动更改或计算机从睡眠中唤醒(,计数器开始加速,每秒更新几次以赶上新的系统时间,或者如果我将时间向后更改,计时器就会停止。
我怎么能解决这个问题,这样它就会简单地";跳跃";到当前时间?
测试扩展:
manifest.json
{
"manifest_version": 3,
"name": "Test timer",
"author": "test",
"description": "Test chrome.alarm",
"version": "0.0.1",
"permissions":
[
"alarms"
],
"action": {},
"background": {
"service_worker": "service_worker.js"
}
}
service_worker.js
let i = 0,
start = new Date().getTime(),
pad = (n,s=2) => ("0"+n).slice(-s),
time = d => pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds()) + "." + pad(d.getMilliseconds(),3);
chrome.alarms.onAlarm.addListener(loop);
console.log("started");
loop();
function loop()
{
const now = new Date().getTime(),
//make sure timer doesn't drift from starting point
next = now - ((now - start) % 1000);
//repeat after 1sec
chrome.alarms.create({ when: next + 1000 });
chrome.action.setBadgeText({text:"" + (i = ++i % 1000)});
console.log("Date:", time(new Date(now)), "alarm:", time(new Date(next)));
}
我已经测试了您的代码,并且有了一些新发现。我遇到了一些服务工作者的问题,我认为这可能与你的";比赛;惊恐
- 如果我一直打开service worker页面,它就会平稳而正确地运行
- 如果我不打开服务人员,它要么会"比赛;或者过一段时间后重新启动,即使我没有更改系统时间或让我的设备进入睡眠状态
由于您使用的是Manifest V3,我必须告诉您Manifest V3存在Service Worker的一些问题。它有时会坏。有关更多信息,您可以阅读此文档。你可以参考这些解决方法。
患者:">医生,我背部疼痛">
医生:">什么时候疼">
患者:">只有当我呼吸时">
医生:">于是一切都解决了。不要再呼吸了">
摆弄系统时间和合唱警报不是很明智。通常情况下,你可以将时钟向前移动(只是为了测试(,但将其向后移动可能会产生不寻常的问题。(除非您先刷新\重新加载扩展(。相反,我们应该调查唤醒电脑后的行为。
此外,这些警报的设计间隔不少于一分钟
我们同意这一限制不适用于开发,但设置1秒警报有点大胆,不是吗
所以,避免呼吸,问题就会自行解决:-(
开玩笑吧,你可以打开一个最小化的选项卡,并在服务人员和该选项卡之间建立连接,形成连续的乒乓球
在服务人员还活着之前,您可以使用setTimeour\setInterval在扩展图标中显示倒计时。
以下是我当前使用performance.now()
和setTimeout
:组合的解决方案
let i = 0,
start = new Date().getTime(),
pad = (n,s=2) => ("0"+n).slice(-s),
time = d => pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds()) + "." + pad(d.getMilliseconds(),3),
timer,
perfPrev = 0;
chrome.alarms.onAlarm.addListener(loop);
console.log("started");
loop();
function loop()
{
const now = new Date().getTime(),
perfNow = performance.now();
//make sure timer doesn't drift from starting point
const next = now - ((now - start) % 1000);
//repeat after 1sec
chrome.alarms.create("loop", { when: next + 1000 });
//detect "racing", when system time changed forward
if (perfNow - perfPrev < 800)
return;
perfPrev = perfNow;
clearTimeout(timer);
//backup plan for when system time changed backwards the alarm won't fire on time
timer = setTimeout(() =>
{
chrome.alarms.clear("loop");
loop();
}, 1000);
chrome.action.setBadgeText({text:"" + (i = ++i % 1000)});
console.log("Date:", time(new Date(now)), "alarm:", time(new Date(next)));
}