Работник службы синхронизации срабатывает только в первый раз

При нажатии кнопки я успешно зарегистрировался для sync и он запускает функциональность, которую я описал в service-worker, Если я не в сети - он ждет, пока браузер установит соединение, а затем срабатывает.

НО - когда я нажимаю кнопку в первый раз, и все в порядке - с тех пор нажатие на кнопку снова успешно регистрируется для sync, но sync событие в сервис-работнике никогда не срабатывает:

self.addEventListener('sync', function(event) {
    console.log('EVENT in SYNC', event);
}

Журнал консоли отображается только при первом нажатии кнопки. Я что-то пропустил?

1 ответ

Решение

Я понял это:) ... и проблема была довольно хромой: sync Обработчик в сервисном работнике возвращал обещание, но это обещание так и не было решено. Как только я добавил resolve() часть в обработчике вернула обещание - все работало нормально.

PS: в демоверсии Джейка Арчибальда sync хендлер делал self.registration.showNotification, который возвращает обещание, и это обещание разрешается после отображения уведомления. На других примерах они упрощают fetch, который также возвращает обещание, и это обещание зависит от успеха. Но на моем примере - я извлекал данные из indexedDB а затем делая fetch, Так что - просто завернул все в

var p = new Promise(function(resolve, reject) {
    // get data from indexedDB .. 
    fetch(...).then(function(response) {
        return response;
    })
    .then(function() {
        // fetch was successful .. 
        resolve();
    });
};
return p;

Таким образом, это работало правильно.

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

В моем случае событие "sync" запускается только один раз. Поэтому я сделал так, как я хотел, зарегистрировавшись в SyncManager после постановки в очередь каждого запроса, который необходимо отправить:

self.addEventListener('fetch', evt=> {
  if(isSuperImportant(evt.request)) {
    evt.respondWith(Promise.resolve(new Response({status: 201})));
    evt.waitUntil(
      myEnqueue(evt.request).then(()=> {
        return self.registration.sync.register('sync-tag'); 
      })
    );
  }
  else {
    // process the non-important requests
  }
});


self.addEventListener('sync', evt=> {
  evt.waitUntil(tryToFlushMyQueue());
});
Другие вопросы по тегам