ServiceWorkerContainer.ready for a specific url script?

ServiceWorkerContainer.ready allows the active ServiceWorkerRegistration service, but if several service workers are involved in the game (for example, service workers from previous page loads, multiple registrations on the same page) there are several service workers to which he can resolve. How can I make sure that a particular working service processes network events when a piece of code is executed?

That is, how can I write a registerReady(scriptURL, options) function that can be used as follows:

 registerReady("foo.js").then(function (r) { // "foo.js" is active and r.active === navigator.serviceWorker.controller fetch("/"); // uses foo.js "fetch" handler }); registerReady("bar.js").then(function (r) { // "bar.js" is active and r.active === navigator.serviceWorker.controller fetch("/"); // use bar.js "fetch" handler }); 
+2
source share
1 answer

First, note that there can only be one active service worker per area, and your client page can be controlled by no more than one and only one service employee. So, when everything is ready, you probably know that the active worker controls your page .

To find out if an arbitrary sw is active, you can register it and check the queue of service workers during registration and listen to the changes in their state. For instance:

 function registerReady(swScript, options) { return navigator.serviceWorker.register(swScript, options) .then(reg => { // If there is an active worker and nothing incoming, we are done. var incomingSw = reg.installing || reg.waiting; if (reg.active && !incomingSw) { return Promise.resolve(); } // If not, wait for the newest service worker to become activated. return new Promise(fulfill => { incomingSw.onstatechange = evt => { if (evt.target.state === 'activated') { incomingSw.onstatechange = null; return fulfill(); } }; }); }) } 

Hope this makes sense to you.

+2
source

All Articles