Синхронизация сервис-воркера срабатывает только в первый раз

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

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

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

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


person pesho hristov    schedule 23.01.2017    source источник
comment
Вы проверили jakearchibald.github.io/isserviceworkerready/demos/sync и подтвердили что ваш код делает то же самое? Если это не поможет, не могли бы вы опубликовать как соответствующие части вашей клиентской страницы, так и кода вашего сервис-воркера?   -  person Jeff Posnick    schedule 26.01.2017
comment
Ох ... Я исправил это ... и забыл записать решение ... извините. Пожалуйста, посмотрите ответ :)   -  person pesho hristov    schedule 26.01.2017


Ответы (2)


Я понял это :) ... и проблема была довольно неубедительной: обработчик 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;

Так все работало правильно.

person pesho hristov    schedule 26.01.2017
comment
Вы должны отметить свой ответ как правильный, если это ваше подходящее решение .. Оно дало мне правильный намек;) - person goemic; 04.02.2018

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

В моем случае событие «синхронизация» запускается только один раз, по замыслу. Итак, я заставил его работать так, как я хотел, зарегистрировавшись в SyncManager после постановки в очередь каждого запроса must-send:

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());
});
person rodix    schedule 04.12.2018