self.skipWaiting() не работает в Service Worker

У меня есть работник службы. Вот событие установки:

self.addEventListener('install', function (event) {
    console.log('Installing Service Worker ...', event);

    return self.skipWaiting()
    .then(() => caches.open(CACHE_STATIC_NAME))
    .then(function (cache) {
        return cache.addAll([
            './file1.html',
            './file2.html'
        ])
    })
});

По какой-то причине, когда я редактирую код рабочего сервиса и обновляю параметр запроса в URL-адресе файла рабочего сервиса, он устанавливается, но не активируется (в соответствии с Chrome DevTools) - хотя я и звонил self.skipWaiting(),

Как ни странно, если я иду в консоль, перейдите в область обслуживания работника и введите self.skipWaiting() Я, это немедленно активируется.

Я пытаюсь понять, что происходит в течение многих часов, и я совершенно в замешательстве. Есть что-то, чего я здесь не хватает?

2 ответа

Старый SW может не останавливаться, пока он все еще выполняет задачи - например, если у него был длительный запрос на выборку (например, сервер отправил события / источник событий или потоки выборки; хотя я не думаю, что веб-сокеты могут вызвать это, поскольку SW будет их игнорировать Я думаю).

Однако я считаю, что в разных браузерах поведение различается. Кажется, что Chrome ждет, пока выполняется существующая задача (так что skipWaiting не удастся...), но Safari, похоже, убивает задачу и активирует новый SW.

Хороший способ проверить, является ли это причиной вашей проблемы, - убить ваш сервер сразу после того, как вы запросите skipWaiting (чтобы убить сетевые соединения). (Кажется, что простой щелчок "Offline" в Dev Tools не уничтожает все работающие соединения, например, EventSources продолжают работать.)

Вы можете заставить ПО игнорировать определенные маршруты (см. Ниже), или вы можете попытаться принудительно завершить запросы (возможно, используя AbortController).

self.addEventListener('fetch', function(event) {
  const { method, url } = event.request;
  if(event.request.method !== "GET") return false;
  if(url === "https://example.com/poll") return false;

  event.respondWith(
    caches.match(match).then(function(response) {
      return response || fetch(event.request);
    })
  );
});

Процесс skipWaiting находится в этой спецификации:

https://w3c.github.io/ServiceWorker/

Но мне не очень ясно, должен ли браузер ждать задач или завершать их (или передавать их в новое ПО?) Перед активацией нового ПО; и, как уже упоминалось, в настоящее время он работает по-разному в разных браузерах...

У меня была такая же проблема.

Я подтвердил свою проблему с помощью уловки, предоставленной @ej.daly, в которой я должен остановить сервер, и сервис-воркер WAITING станет активным через несколько минут.

После этого я применил хак в своем коде: перезагрузите окно, если WAITING service worker не будет активирован в течение следующих 3 секунд.

Кстати, я разрабатываю библиотеку, чтобы упростить установку обслуживающего персонала для различных (часто используемых) сценариев в нашей компании. Взгляните на https://github.com/DreamworldSolutions/workbox-installer

Другие вопросы по тегам