Время `postMessage` внутри обработчика события` fetch` - PullRequest
0 голосов
/ 09 февраля 2020

У меня есть простой сервисный работник, который на 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);
});
<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");
    })()
  );
});

Когда я смотрю журналы консоли, становится ясно, что прослушиватель событий message зарегистрирован после сообщение размещены работником сервиса. Тем не менее прослушиватель событий все еще получает сообщение.

enter image description here

Я подозреваю, что это потому, что сообщения планируются асинхронно:

postMessage () планирует отправку MessageEvent только после завершения всех ожидающих контекстов выполнения. Например, если postMessage () вызывается в обработчике событий, этот обработчик событий будет выполняться до завершения, как и все остальные обработчики для того же события, до отправки MessageEvent.

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

Однако я не уверен, что это означает в этом конкретном c примере. Например, когда обработчик события fetch завершился, гарантированно ли работал клиент JavaScript, и, следовательно, прослушиватель события сообщения будет зарегистрирован?

У меня есть приложение большего размера, которое выполняет нечто подобное к вышесказанному, но клиент JavaScript запускается чуть позже при загрузке страницы, поэтому я хотел бы знать, когда именно должен быть зарегистрирован прослушиватель событий, чтобы избежать условий гонки и гарантировать, что сообщение, отправленное работником службы, будет получил.

1 Ответ

0 голосов
/ 09 февраля 2020

По умолчанию все сообщения, отправляемые работником службы управления страницей на страницу (с помощью Client.postMessage ()), ставятся в очередь во время загрузки страницы и отправляются после загрузки документа HTML страницы. и проанализировал (т.е. после того, как событие DOMContentLoaded срабатывает). Можно начать отправлять эти сообщения раньше, вызвав ServiceWorkerContainer.startMessages (), например, если вы вызвали обработчик сообщений с помощью EventTarget.addEventListener () до завершения загрузки страницы, но хотите сразу начать обработку сообщений.

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

...