2

Beschreibung:Service-Worker skipWaiting nicht in der Lage zur Zeit aktivieren SW warten

Wir sw precache verwenden die Skripte vor der Hand für das Caching, damit die Skripte aktualisieren wir Reload-Option geben, für, dass wir das hören überspringen Arbeiter Nachricht der neu installieren Servicemitarbeiter aus unbekanntem Grund warten wir nicht richtig

importScript

// GETTING OLD SW reference (self) and NOT getting newly installed SW reference 

self.addEventListener('message', function(event) { 
    *// not working* 
    self.skipWaiting(); 
}); 



// But if we put skipWaiting() in 'install' listener 
// it is getting correct new SW reference and working correctly 

self.addEventListener('install', function(event) { 
    // self.skipWaiting(); 
}); 
bekommen

SW Registrierung

if('serviceWorker' in window.navigator) { 
     window.addEventListener('load', function() { 
     window.navigator.serviceWorker.register("/serviceWorker.js").then(function(registration) { 
      console.log("ServiceWorker registration successful with scope: ", registration); 
      registration.onupdatefound = function() { 
      console.log('NEW WILD WORKER HAS SPAWNED.!', registration); 
      var installedWorker = registration.installing; 
      installedWorker.onstatechange = function() { 
       if (installedWorker.state === 'installed') { 
       if (navigator.serviceWorker.controller) { 
        console.log('Updated content is available RELOAD!', navigator.serviceWorker.controller); 
        var el = document.getElementById('feature'); 
        el.style['display'] = 'block'; 
       } 
       } 
      } 
      } 
     }).catch(function(error) { 
      console.error("ServiceWorker registration failed: ", error); 
     }); 
     }); 
     window.navigator.serviceWorker.addEventListener('controllerchange', function() { 
     console.log('SERVICE WORKER UPDATED'); 
     }); 
    } 

webpack Config

new SWPrecacheWebpackPlugin({ 
     cacheId: 'pwa', 
     filename: 'serviceWorker.js', 
     staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/, /_nch\.[0-9a-z]+\.[js, css]+/g, /webpackManifest\.[0-9a-z]+\.js/g, /.DS_Store\.[0-9a-z]+/g], 
     importScripts: ['offline/offline.1a2b3c4df1.js'], 
     dontCacheBustUrlsMatching: /./, 
     minify: false, 
     skipWaiting: false, 
     runtimeCaching: [ { 
      urlPattern: /_nch\.[0-9a-z]+\.[js, css]+/g, 
      handler: 'fastest', 
      options: { 
      cache: { 
       name: 'jd-internal-script', 
       maxEntries: 10, 
      }, 
      }, 
     }, { 
      urlPattern: /webpackManifest\.[0-9a-z]+\.js/g, 
      handler: 'networkFirst', 
      options: { 
      cache: { 
       name: 'jd-root-doc', 
      }, 
      }, 
     }], 
     }), 

Antwort

2

Die beste Dokumentation für skipWaiting() kann bei https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle#skip_the_waiting_phase

Sie entweder gefunden werden können Rufen Sie es bedingungslos im Handler install an, oder folgen Sie dem Modell, das Sie zu tun scheinen, das ist für ein message Ereignis zu hören und skipWaiting() bedingt aufrufen.

Wenn Sie die bedingte Route wählen, sollten Sie den Code Ihrer Clientseite so ändern, dass der Service-Mitarbeiter, den Sie registrieren, den waiting-Status eingibt und dem Benutzer die Möglichkeit gibt, mit der Seite zu interagieren ergibt in einer entsprechenden postMessage() den Service-Arbeiter zu skipWaiting() zu erzählen. Basierend auf dem, was Sie gerade gesagt haben, haben Sie das versucht, aber es sieht so aus, als würden Sie die Nachricht an die falsche Service-Worker-Instanz senden.

Hier ist, was Sie Seite Code sollte wie folgt aussehen:

// On your page: 
if ('serviceWorker' in navigator) { 
    window.addEventListener('load', function() { 
    navigator.serviceWorker.register('service-worker.js').then(function(reg) { 
     reg.onupdatefound = function() { 
     var newSW = reg.installing; 
     newSW.onstatechange = function() { 
      if (newSW.state === 'waiting') { 
      // This assumes there's a button with id='skip-waiting-button' that 
      // users should click to get the new SW to activate immediately. 
      var button = document.querySelector('#skip-waiting-button'); 
      button.addEventListener('click', function() { 
       newSW.postMessage('skipWaiting'); 
      }); 
      // Assume that 'display' is 'none' initially. 
      button.style.display = 'inline'; 
      } 
      // Handle whatever other SW states you care about, like 'active'. 
     }; 
     }; 
    }) 
    }); 
} 

// In your service worker: 
self.addEventListener('message', event => { 
    if (event.data === 'skipWaiting') { 
    self.skipWaiting(); 
    } 
}); 
+0

Danke, dass Sie diese Arbeit gemacht haben.Kann ich für die Implementierung von Service-Mitarbeitern zur Workbox wechseln, da ich derzeit sw-precache und sw-toolbox verwende, um dies zu erreichen. Daher wäre es hilfreich, wenn Sie einige Ressourcen zur Workbox-Implementierung mit Webpack bereitstellen könnten. –

+0

installingWorker.onstatechange in diesem wir erhalten Fehler installerWorker ist undefined, so dass anstelle von newSW verwendet werden muss? –

+0

newSW.state = 'waiting' Dies erfüllt nicht statt dessen wir newSW.state = 'installiert'. Daher können wir den Wartezustand nicht anzapfen. –

0

Also hier ist, was ich denke ... Ihr neuer Servicemitarbeiter immer noch wartet .. also der Ereignis-Listener noch auf ist Älterer Service-Mitarbeiter .. Alle Nachrichten, die Sie senden, werden immer noch von der älteren sw (als der neue wartet) gefangen.

Wenn Ihr nur Fall ist die neue sw zu handeln zu bekommen, können Sie einfach aktualisieren Sie Ihre Seite, anstatt die Nachricht zu senden

+0

Aber wenn ich das tun, dann erste Strategie arbeiten cachen nicht, weil die webpackManifest und doc zur Laufzeit zwischengespeichert werden, weil der dynamischen doc durch ausdrückliche erzeugt. In diesem Fall muss ich zur ersten Strategie des Netzwerks wechseln. –

+0

Sprechen wir hier über Pakete oder APIs oder was genau? – prateekbh

+0

Es handelt sich nur um Pakete. Wenn der Client eine Anforderung für doc stellt, wird vom Server ein Dokument gesendet. Wenn das Dokument analysiert wird, wird der Service Worker heruntergeladen und der Service Worker wird installiert und aktiviert. Danach speichert er diese Ressource (Lieferant usw.) vorab. Jetzt, wenn ich einige Änderungen an meinem Skript mache und meinen neuen Build veröffentliche. Dann, wenn das nächste Mal Client den Server trifft, findet es eine Änderung in der Service-Worker-Datei und die gleiche wird heruntergeladen und installiert und geht in den Wartezustand, so zeige ich jetzt eine Pop-Nachricht && als Benutzer klickt ich rufe self.skipwaiting und dann Seite –

Verwandte Themen