2017-08-18 13 views
14

मैं क्या हासिल करने की कोशिश कर रहा हूँ:कैसे: ServiceWorker जांच करता है, तो अद्यतन करने के लिए तैयार

  • लोडर/स्पिनर

  • अगर साथ पेज प्रस्तुत करना service-worker.js पंजीकृत है और सक्रिय है, तो अद्यतन के लिए जाँच

    • यदि कोई अपडेट नहीं है, तो लोडर
    • हटाएंऔर नया संस्करण स्थापित किया है, तो रजिस्टर service-worker.js
      • जब updatefound, नया अर्थ स्थापित किया गया था, लोडर

    मैं के लिए sw-precache मॉड्यूल का उपयोग कर रहा हटाने पेज

  • किसी और को फिर से लोड मुझे service-worker.js उत्पन्न करने और पंजीकरण कोड के बाद:

    window.addEventListener('load', function() { 
    
        // show loader 
        addLoader(); 
    
        navigator.serviceWorker.register('service-worker.js') 
        .then(function(swRegistration) { 
    
         // react to changes in `service-worker.js` 
         swRegistration.onupdatefound = function() { 
         var installingWorker = swRegistration.installing; 
         installingWorker.onstatechange = function() { 
          if(installingWorker.state === 'installed' && navigator.serviceWorker.controller){ 
    
          // updated content installed 
          window.location.reload(); 
          } else if (installingWorker.state === 'installed'){ 
    
          // new sw registered and content cached 
          removeLoader(); 
          } 
         }; 
         } 
    
         if(swRegistration.active){ 
         // here I know that `service-worker.js` was already installed 
         // but not sure it there are changes 
         // If there are no changes it is the last thing I can check 
         // AFAIK no events are fired afterwards 
         } 
    
        }) 
        .catch(function(e) { 
         console.error('Error during service worker registration:', e); 
        }); 
    }); 
    

    spec पढ़ने के बाद यह स्पष्ट है कि updatenotfound जैसे कुछ के लिए कोई हैंडलर नहीं हैं। ऐसा लगता है कि serviceWorker.register जांचता है कि service-worker.jsget-newest-worker-algorithm चलाकर आंतरिक रूप से बदल गया है, लेकिन मैं सार्वजनिक एपीआई के माध्यम से सामने आने वाले समान तरीकों को नहीं देख सकता।

    मुझे लगता है कि मेरी विकल्प हैं: सेवा कार्यकर्ता पंजीकरण के बाद कुछ सेकंड के लिए

    • इंतजार हो जाता है सक्रिय देखने के लिए अगर onupdatefoundservice-worker.js कोड से
    • आग कस्टम घटनाओं निकाल दिया जाता है, तो कैश अपडेट नहीं किए जाने

    कोई अन्य सुझाव?


    संपादित करें:

    मैं कुछ कोड है जो दप पंजीकरण और दप ग्राहक के बीच postMessage() का उपयोग करके इस समस्या को हल करती है के साथ आया है (के रूप में @pate सुझाव)

    बाद

    डेमो एसडब्ल्यू क्लाइंट और एसडब्ल्यू पंजीकरण के बीच postMessage के माध्यम से चेक प्राप्त करने का प्रयास करता है, लेकिन विफल रहता है क्योंकि एसडब्ल्यू कोड पहले ही कैश किया गया है DEMO


    संपादित करें:

    तो अब से ऐसा लगता है कि मैं लागू नहीं कर सकते जो मैं चाहता है क्योंकि:

    1. जब सेवा कार्यकर्ता सक्रिय है आप दप में कुछ कोड का मूल्यांकन करके अद्यतनों की जाँच नहीं कर सकते हैं - यह अभी भी एक ही कैश किए गए एसडब्ल्यू है,
    2. में आपको कोई बदलाव नहीं है, आपको onupdatefound के लिए प्रतीक्षा करने की आवश्यकता है, एसडब्ल्यू
    3. में परिवर्तनों की अधिसूचना कुछ भी नहीं है पुराने दप कीआता onupdatefound
    4. अगर कोई परिवर्तन होता है से पहले, कुछ भी आग के बाद activation
    5. दप पंजीकरण update() अपरिपक्व है, बदलता रहता है, Starting with Chrome 46, update() returns a promise that resolves with 'undefined' if the operation completed successfully or there was no update
    6. स्थगित करने के लिए दृश्य प्रतिपादन करने से इनकी है के रूप में वहाँ कोई स्पष्ट उत्तर नहीं है समय-समाप्ति सेट इसे कब तक सेट किया जाना चाहिए, यह एसडब्ल्यू आकार पर भी निर्भर करता है, साथ ही
  • उत्तर

    0

    मेरे दिमाग में पॉप अप करने का एकमात्र तरीका लोडर को सामान्य रूप से शुरू करना है और फिर इसे इंस्टॉल करने में सेवा-कार्यकर्ता में हटा देना है समारोह। मैं यह कोशिश करूंगा, आपकी सेवा-कार्यकर्ता.जेएस:

    self.addEventListener('install', function(e) { 
        console.log('[ServiceWorker] Install'); 
        e.waitUntil(
        caches.open(cacheName).then(function(cache) { 
         console.log('[ServiceWorker] Caching app shell'); 
         return cache.addAll(filesToCache); 
        }).then(function() { 
         ***removeLoader();*** 
         return self.skipWaiting(); 
        }) 
    ); 
    }); 
    
    +0

    यह देखा जैसे कि यह एक मुद्दे को हल करना चाहिए, लेकिन इस घटना के केवल कार्यकर्ता परिवर्तन करता है, तो निकाल दिया जाता है। https://w3c.github.io/ServiceWorker/#service-worker-global-scope-install-event –

    3

    फैबियो द्वारा प्रदान किया गया दूसरा उत्तर, काम नहीं करता है। सेवा कार्यकर्ता स्क्रिप्ट के पास डोम तक पहुंच नहीं है। डीओएम से कुछ भी निकालना संभव नहीं है, उदाहरण के लिए, सर्विस वर्कर के अंदर से डीओएम तत्वों को संभालने वाले किसी भी डेटा में हेरफेर करें। वह स्क्रिप्ट किसी साझा स्थिति के साथ अलग से चलती है।

    हालांकि, आप क्या कर सकते हैं, वास्तविक पृष्ठ-चल रहे जेएस और सेवा कर्मचारी के बीच संदेश भेजते हैं। मुझे यकीन नहीं है कि ओपी क्या पूछ रहा है, यह करने का सबसे अच्छा तरीका है लेकिन इसे प्राप्त करने के लिए इसका उपयोग किया जा सकता है।

    1. पृष्ठ पर एक onmessage हैंडलर रजिस्टर
    2. दप के सक्रिय से संदेश भेजें या पेज
    3. अधिनियम तदनुसार जब संदेश पेज

    मेरे पास है पर प्राप्त होता है करने के लिए घटना को स्थापित मैंने एसडब्ल्यू संस्करण संख्या को एसडब्ल्यू के अंदर एक चर में रखा। मेरे एसडब्ल्यू ने उस संस्करण संख्या को पृष्ठ पर पोस्ट कर दिया है और पृष्ठ ने इसे ब्राउज़र के स्थानीय स्टोरेज में संग्रहीत किया है। अगली बार जब पृष्ठ लोड हो जाता है तो एसडब्ल्यू पृष्ठ पर वर्तमान संस्करण संख्या पोस्ट करता है और ऑनमेज हैंडलर वर्तमान में संग्रहीत संस्करण संख्या से इसकी तुलना करता है।यदि वे समान नहीं हैं, तो SW को कुछ संस्करण संख्या में अद्यतन किया गया है जो mssage में शामिल था। उसके बाद मैंने संस्करण संख्या की स्थानीय स्टोरेज प्रति अपडेट की है और इसे और वह किया है।

    यह प्रवाह अन्य तरीकों से भी किया जा सकता है: पृष्ठ से संदेश को SW में भेजें और SW को कुछ जवाब दें, फिर तदनुसार कार्य करें।

    मुझे आशा है कि मैं अपने विचारों की व्याख्या करने में सक्षम था स्पष्ट रूप से :)

    +0

    ग्रेट सुझाव, मैंने एक हैकड समाधान [प्लंकर डेमो] के साथ एक प्लंकर किया है (https: //embed.plnkr सह/s9ozu0ntcQuD5touoWIr /)। अब के लिए और अधिक प्रतिक्रियाओं के लिए इंतजार करेंगे। –

    +0

    हां, मैं पूरी प्रक्रिया की आपूर्ति करने का दावा नहीं कर रहा था, लेकिन केवल अवधारणा। जब मैंने एसडी स्क्रिप्ट में *** removeLoader(); *** लिखा, तो मेरा मतलब था कि वहां कुछ करना है (एक संदेश? एक ईवेंट जांच?)। –

    +0

    एक चेतावनी यह है कि अगर एसडब्ल्यू अभी तक पंजीकृत नहीं है (पहली स्थापना), लेकिन यदि ऐसा है तो घटनाओं को एसडब्ल्यू से निकाल दिया जा रहा है जो पहले से सक्रिय है और यह कहेंगे कि कुछ भी नहीं बदला है। तो ऐसा लगता है कि आप गारंटी नहीं दे सकते कि 'ऑनअपडेटफाउंड' उनको प्राप्त करने के बाद ट्रिगर नहीं किया जाएगा। –

    संबंधित मुद्दे