首页 > 解决方案 > 在 Service Worker 的事件处理程序中去抖动异步工作

问题描述

对于 Firefox,在 ServiceWorker 中使用 lodash debounced 函数是可以的。它们等待分配的超时时间,如果再次调用去抖函数,则计时器会重置。

然而,对于 Chrome 来说,没有什么能像预期的那样工作:去抖函数一调用就会调用内部函数,并且不会等待计时器中的重置。

有没有人遇到过这个问题?任何解决方法?

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

标签: cross-browserlodashservice-workerdebounce

解决方案


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

  • 从 aExtendableEvent
  • 通过将完成的承诺传递给 that 的waitUntil()方法来包装工作ExtendableEvent

FetchEvent是一个ExtendableEvent。)

如果你没有这样做,那么浏览器不能保证你的异步任务将在服务工作线程被杀死之前完成。不同的浏览器在终止服务工作线程方面或多或少具有侵略性,因此这可能解释了您所看到的不同行为。

lodashdebounce()不提供对 Promise 的内置支持,因此您要么必须自己包装东西,要么找到合适的替代库。请注意,无论您使用哪种方法,请确保您使用最终会解决的承诺,即使操作已消除抖动。否则,如果你传递了一个没有解析为 的 promise waitUntil(),你最终会让 service worker 存活太久。

撇开 promise-returning 的实际实现不谈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));
  }
});

推荐阅读