Итак, на сегодняшний день фоновая синхронизация в Chrome пытается отправить запросы в очереди 3 раза (никогда не объяснялось в документации по рабочему ящику или фоновой синхронизации):
- Первый раз: при запросефактически выполняется в первый раз, и браузер обнаруживает, что пользователь не имеет соединения, поэтому он помещает запрос в indexedDB.
- Второй раз: ровно через 5 минут после первой попытки.
- Третий раз: Ровно через 15 минут после первой попытки.
Если у пользователя нет соединения через 15 минут, то запросы просто застревают в indexedDB, пока новый запрос в очереди не попытается вытолкнуть остальные.Это не очень полезно в сценарии, когда мы ожидаем, что у пользователя не будет подключения к Интернету в течение нескольких часов.
Существуют планы (с 2016 года!) Реализовать PeriodicSync, который позволил бы разработчику выбирать, сколько раз и сколько времени потребуется браузеру для синхронизации, но он так и не был реализован, см .:https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/periodicSync
Я придумал неуклюжее решение, хотя, возможно, не самое лучшее, но оно делает то, что мне нужно.Существует событие синхронизации, которым мы можем манипулировать, чтобы повторить запросы, которые мы застряли в indexedDB.Мы должны использовать класс Workbox Queue вместо плагина.
// our service worker file
// we create a push notification function so the user knows when the requests are being synced
const notificate = (title, message) => {
self.registration.showNotification(title, {
body: message,
icon: '/image.png',
tag: 'service-worker'
})
}
// let's create our queue
const queue = new workbox.backgroundSync.Queue('myQueue', {
callbacks: {
requestWillEnqueue: () => {
notificate('You are offline! ?', 'Your request has been submitted to the Offline
queue. The queue will sync with the server once you are back online.')
}
});
// sync event handler
self.addEventListener("sync", (ev) => {
queue.replayRequests().then((a) => {
notificate('Syncing Application... ?', 'Any pending requests will be sent to the
server.');
}).catch(
notificate('We could not submit your requests. ❌', 'Please hit the \'Sync Pending
Requests\' button when you regain internet connection.')
);
});
Теперь внутри нашего файла представления HTML / React / Node мы можем сделать:
// this will trigger our Sync event
<button type="button" onClick={navigator.serviceWorker.ready.then(reg =>
reg.sync.register('myEvent'))}>{'Sync Pending
Requests'}</button>
Обратите внимание, что я создал HTMLкнопка, которая заставляет моего сервисного работника запускать queue.replayRequests (), поэтому функция фоновой синхронизации не происходит автоматически, мне нужно вручную нажать кнопку, чтобы это произошло.