首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果系统时间改变,chrome.alarms正在“竞相”追赶。

如果系统时间改变,chrome.alarms正在“竞相”追赶。
EN

Stack Overflow用户
提问于 2022-08-04 01:48:02
回答 3查看 116关注 0票数 0

我使用chrome.alarm在扩展图标上显示倒计时,它每秒钟更新一次。我面临的问题是,如果我改变系统的时间前进(手动或如果计算机从睡眠中醒来),计数器开始运行,每秒钟更新几次试图赶上新的系统时间,或者如果我改变时间倒转,计时器停止。

我如何解决这个问题,这样它就可以简单地“跳”到当前时间了?

测试扩展:

manifest.json

代码语言:javascript
复制
{
  "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

代码语言:javascript
复制
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)));
}
EN

回答 3

Stack Overflow用户

发布于 2022-08-05 09:42:52

我测试了你的代码,我有了一些新发现。我遇到了一些服务人员的问题,我认为这可能与您的“赛车”警报有关。

  1. 如果始终保持服务工作人员页面打开,它将顺利正常运行。
  2. 如果不打开服务工作人员,它将在一段时间后“运行”或重新启动,即使我不更改系统时间或让我的设备处于休眠状态。

由于您使用的是Manifest V3,所以我必须告诉您,Manifest V3存在一些服务工作者问题。它有时会坏掉。有关更多信息,您可以阅读此doc。您可以肯定地参考这些解决方案。

票数 2
EN

Stack Overflow用户

发布于 2022-08-04 09:46:12

病人:“医生,我背疼”。

医生:“什么时候疼?”

病人:“只有当我呼吸时”

医生:“这一切都解决了,别再呼吸了”

摆弄系统时间和chorme.alarms是不明智的。通常,您可以将时钟向前移动(只是为了测试),但是将时钟倒转可能会产生不寻常的问题。(除非您先刷新\重新加载扩展)。相反,我们应该调查一下醒来后的行为。

此外,这些警报器的设计间隔不少于一分钟。

我们同意这个限制不适用于开发,但是设置一秒警报有点大胆,不是吗?

因此,避免呼吸,问题就会自行解决:)

撇开玩笑,你可以打开一个最小化的标签,并建立一个连接的服务人员和那个标签,使一个持续的乒乓球。

直到服务人员还活着,您才能使用setTimeour\ setInterval来支付扩展图标中的倒计时。

票数 0
EN

Stack Overflow用户

发布于 2022-08-11 01:00:54

下面是我使用performance.now()setTimeout结合使用的当前解决方案

代码语言:javascript
复制
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)));
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73229521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档