在 Service Worker 的事件处理程序中去除异步工作

Debouncing asynchronous work inside of a service worker's event handler

在 ServiceWorker 中使用 lodash 去抖函数对于 Firefox 是可以的。他们等待指定的超时时间,如果再次调用去抖功能,计时器将重置。

但是,对于 Chrome,没有任何事情按预期进行:去抖函数在调用后立即调用内部函数,不会等待计时器中的重置。

有人 运行 遇到过这个问题吗?有什么解决方法吗?

我正在使用它来等待空闲用户(一段时间内不再获取)发送记录的分析。

在没有看到您的示例代码的情况下完全调试它有点困难,但一般的经验法则是,如果您正在安排异步工作,您希望在服务工作者事件处理程序的同步执行之外完成, 你需要

  • ExtendableEvent
  • 内部工作的时间表
  • 通过将完成承诺传递给 ExtendableEventwaitUntil() 方法来包装工作。

(FetchEvent 是一个 ExtendableEvent。)

如果您未能做到这一点,那么浏览器将无法保证您的异步任务会在服务工作线程被终止之前完成。不同的浏览器或多或少会主动终止服务工作者线程,因此这可以解释您所看到的不同行为。

lodash 的 debounce() 不提供对承诺的内置支持,因此您要么必须 ,要么找到合适的替代库。请注意,无论您使用什么方法,请确保您使用最终会解决的承诺,即使操作是去抖动的。否则,如果您传递一个未解析为 waitUntil() 的承诺,您最终会使服务工作人员保持活动太久。

抛开承诺返回的实际实现 debounceWithPromises(),一般结构如下所示:

self.addEventListener('fetch', (event) => {
  if (/* some criteria is met */) {
    // As soon as the promise passed to respondWith() resolves,
    // the response will start being fed to the client.
    event.respondWith(generateResponse(event);

    // Independent of the response generation, the promise returned
    // by the hypothetical debounceWithPromises() will keep the
    // service worker alive until it resolves or rejects (or until a
    // browser-specific maximum lifetime is reached).
    event.waitUntil(debounceWithPromises(logStats));
  }
});