当前位置: 首页 > 知识库问答 >
问题:

服务工作人员获取事件处理程序中postMessage的时间

牧甫
2023-03-14

我有一个简单的服务人员,在fetch上向客户发布消息:

// main.js

navigator.serviceWorker.register("./service-worker.js");

console.log("client: addEventListener message");
navigator.serviceWorker.addEventListener("message", event => {
  console.log("client: message received", event.data);
});
html prettyprint-override"><script src="main.js"></script>
// service-worker.js

self.addEventListener("fetch", event => {
  console.log("service worker: fetch event");

  event.waitUntil(
    (async () => {
      const clientId =
        event.resultingClientId !== ""
          ? event.resultingClientId
          : event.clientId;
      const client = await self.clients.get(clientId);

      console.log("service worker: postMessage");
      client.postMessage("test");
    })()
  );
});

当我查看控制台日志时,很明显,消息事件侦听器是在服务人员发布消息之后注册的。尽管如此,事件侦听器仍然接收消息。

我怀疑这是因为消息是异步调度的:

postMessage()计划仅在所有挂起的执行上下文完成后发送MessageEvent。例如,如果在事件处理程序中调用postMessage(),则该事件处理程序将在发送MessageEvent之前运行到完成,同一事件的任何剩余处理程序也将如此。

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#Notes

然而,我不确定这在这个具体的例子中意味着什么。例如,当fetch事件处理程序运行到完成时,是否保证客户端JavaScript已运行,因此将注册消息事件侦听器?

我有一个更大的应用程序正在做类似于上面的事情,但是客户端JavaScript在页面加载中稍微晚一点运行,所以我想知道什么时候必须注册事件监听器以避免竞争条件并保证消息由服务人员发布将被接收。

共有1个答案

桓信鸥
2023-03-14

默认情况下,从页面的控制服务工作人员发送到页面的所有消息(使用Client.postMessage())在页面加载时排队,一旦页面的超文本标记语言文档被加载和解析(即在DOMContentLoade之后),就会被分派事件火灾)。可以通过调用ServiceWorkerContainer.startMessages()提前开始分派这些消息,例如,如果您在页面加载完成之前使用EventTarget.addEventListener()调用了消息处理程序,但希望立即开始处理消息。

https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/startMessages

 类似资料:
  • 是浏览器中可用的事件。服务工作者代码是否支持没有DOM访问权限的等效事件? 我看到的所有示例代码都在处理请求的过程中检查网络状态。为了向服务器或云提交本地更新,最好立即响应网络可用性。 我能找到的最好的文档是https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope它只列出了这些事件: 激活 其中,sync看起

  • 我想在获取事件侦听器中访问我的服务工作者的作用域。我计划的解决方法是使用,但在服务人员内部不可用。我还尝试使用ServiceWorkerRegistration。作用域(MDN doc),它将返回我想要的值,但这在fetch事件处理程序中也是不可访问的。 我希望有类似的(在注册处理程序中可用),但用于获取处理程序。这可能吗?

  • 我注意到,当服务工作人员脚本本身加载到浏览器中时,不再触发服务工作人员的读取事件。例如,当我们有一个新版本的服务辅助角色时,旧的服务辅助角色读取事件不会被触发。因此,旧的服务工作者不能再检查新服务工作者的内容。 我确信这以前是可能的,我想知道这是否是一个bug,或者是否对此进行了任何更改。我在官方存储库或W3C草稿中没有找到与此更改相关的任何内容。 为了验证fetch事件没有被触发,我用版本号(参

  • 我有两个独立的应用程序运行在同一服务器上。 null 我已经实现了从用户管理到钱包管理的事件来源。它运行得很好。 但是,当我将从钱包管理应用程序中的事件处理程序发布新事件时,我将收到以下错误消息日志。 以下是我的日志详细信息

  • 这与渐进式Web应用程序中使用的serviceworker API有关。有人能帮我理解服务人员安装事件和激活事件之间的区别吗? 以下是我的理解, 安装事件是注册服务辅助程序后发生的第一个事件 除了上面的陈述,我的问题是两个事件之间到底有什么区别,它们都是一个接一个地运行的,如果是这样,为什么我们需要两个事件? 更新:共享可能有帮助的资源。我正在读这个。https://developers.goog

  • 问题内容: 情况: 活动绑定到已启动的前台服务。 服务将本地活页夹分发给活动。 活动通过getService()调用获取对服务的引用。 活动希望使用消息 直接 与服务中运行的线程进行通信。它从活动中调用mService.getThreadHandler()方法。 问题: 如何从当前正在运行的线程中将Handler放入活动活动中,以便可以将消息直接发布到线程的messagequeue中? 我不需要在