问题
I'm currently learning how to use Background Sync as to allow users to PUT/POST changes while using a web app offline.
I followed the instructions given by Jake Archibald in Introducing Background Sync , and everything worked great... as long as I register the Background Sync when the web app was loaded while being online. What I mean by that is:
Steps that work:
- While online I open web app
- I turn offline mode on in the network tab
- I click some buttons that register a Background Sync.
- I turn offline mode off, so app goes back online.
- Background Sync is triggered.
Steps that cause it to stop working:
It stops working completely, even in the above scenario if I do the following:
- While on a different site, I turn offline mode on in the network tab.
- I navigate to my web app, which is available offline thanks to the service worker.
- I click some buttons that are supposed to register a Background Sync.
- I turn offline mode off in the network tab.
- Nothing happens.
- After I go to the Application tab, and unregister the service worker, and try again from a fresh installation, the first steps work, but the second set of steps keeps breaking the Background Sync
Code:
In page:
//requesting a one-off sync:
navigator.serviceWorker.ready.then(function (reg) {
return reg.sync.register('sync-tag');
}).catch(function (e) {
console.error(e, "System was unable to register for a sync");
});
In Service Worker
self.addEventListener('sync', event => {
if (event.tag == 'sync-tag') {
event.waitUntil( doStuff() )
}
});
Update
When the code works, I used the following code to keep track of tags sent to registration:
navigator.serviceWorker.ready.then(function (reg) {
console.log('before', reg.sync.getTags());
reg.sync.register('sync-tag');
console.log('after', reg.sync.getTags());
}).catch(function (e) {
console.error(e, "System was unable to register for a sync");
});
When using the steps that work, I get
before: resolved to an empty array
after: resolved to an array with one tag ['sync-tag']
When using the steps that cause it to stop working:
before: resolved to an array with one tag ['sync-tag']
after: resolved to the same array above
This leads me to believe the sync registration happens, but the service worker isn't listening
anymore. And no matter what I do, like close the browser tab, refresh the page when online, wait a while, the service worker just won't listen
to sync events anymore.
I understand that is up to the browser to decide when to make the Background Sync, but I just don't understand why this isn't working. Unless the expected behavior is to expect the user to visit the web app when online, I think I'm getting something wrong.
Thank you for your patience, and any help understanding how to make Background Sync work will be appreciated.
回答1:
Ok, I feel stupid. The browser is indeed the one that decides when to do the background sync.
The behavior I expected is wrong:
- Access app while offline.
- POST/PUT changes with Background Sync
- Go back online, refresh page see changes right away
Behavior the browser actually implemented:
Accessing app while online:
- Access app online.
- app goes offline (manually or not)
- POST/PUT changes with Background Sync
- app goes online, and refresh
- Changes are instant, since Sync happens as soon as app goes online. Browser is able to detect the change from online, to offline back to online?
Accessing app while offline
- Access app while offline.
- POST/PUT changes with Background Sync.
- app goes online, and refresh
- Changes aren't instant. Somehow the browser decides not to make the sync yet.
- Close browser completely, and come back to page
- The Browser syncs.
So is hard to know when the Browser will perform the sync, and only when accessing app while online, does the browser syncs if it detects a change from offline then online in same session (no refresh?)
来源:https://stackoverflow.com/questions/51978911/javascript-background-sync-stops-working-if-page-is-loaded-refreshed-while-offli