javascript - 使用 service worker 的带有通知的计时器

标签 javascript timer settimeout service-worker

我想创建一个计时器,它在通知点击时开始倒计时。

只要中断时间少于一分钟,我的示例就可以正常工作。 当中断时间超过一分钟时,service worker 停止工作。

index.html

<!DOCTYPE html>
<html>
<body>
<button onclick="notify();">notify</button>
</body>
<script>
  function notify() {
    const items = ["First", "End of the break", "Second"];
    const options = { data: items };

    if ('serviceWorker' in navigator) {
      Notification.requestPermission()
        .then(() => navigator.serviceWorker.register('sw.js'))
        .then(() => navigator.serviceWorker.ready
        .then((s) => {
          s.showNotification('Click to begin', options);
        }))
      .catch(e => console.log(e.message));
    }
  }
</script>
</html>

sw.js

let data = [];
let num = 0;

self.onnotificationclick = (event) => {
  event.notification.close();
  if (event.notification.data) {
    ({ data } = event.notification);
  }

  if (num < data.length) {
    setTimeout(() => {
      self.registration.showNotification(data[num]);
      num += 1;
    }, num % 2 === 0 ? 1 : 3000);
  }
};

我知道sw.js中不应该有setTimeout,但这是最接近我想要实现的点。

有没有办法构建一个计时器,当您点击通知时开始倒计时并通知您倒计时结束?

最佳答案

(这是一个很长的答案,因为您的问题有几件事要讨论)

Service Worker 的设计方式是您应该尽快完成工作并将控制权交还给浏览器。这是通过 event.waitUntil(<promise>) 完成的通过不解决传入的 promise 来告诉浏览器您很忙的功能。

在上面的示例中,您没有使用 event.waitUntil()这可以延长服务人员的生命。

例如,您可以尝试:

self.onnotificationclick = (event) => {
  event.notification.close();
  if (event.notification.data) {
    ({ data } = event.notification);
  }

  if (num < data.length) {
    event.waitUntil(new Promise(function(resolve, reject) {
        setTimeout(() => {
            self.registration.showNotification(data.num);
            resolve();
        }, 3000);
    })
  }
};

但是如果您设置的超时被认为太长(并且由浏览器决定什么太长),浏览器可以终止 service worker,从而导致不可预测的体验您的用户。

这是因为您的预期用例通常不是 Service Worker API 的设计目的。有替代 API 的建议,但没有一个获得关注(或者至少我不知道 - 尽管那是一段时间了)。

另一个注意事项:在 service worker 中使用全局变量应谨慎使用。就像我说的,service worker 可以频繁启动和终止,因此从 indexDB 读取/写入可能更适合存储信息。

关于javascript - 使用 service worker 的带有通知的计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53178703/

相关文章:

javascript - Node js : Wait for 100 requests to get completed

swift - 为什么我的 swift 计时器一直在加速?

javascript - setTimeout() - 分割 slider 中的输出不正确

javascript - 如何在 react 中使用 setInterval?

javascript正则表达式单行

javascript - 在 Node.js 中高级编写文件

javascript - $(document).ready 已停止工作

Android 我可以运行多少个线程?

java - 游戏服务器开启计时器

Javascript setTimeout 与 for 循环中的函数