Service Worker控制器更改永远不会触发

时间:2016-10-20 18:02:17

标签: javascript service-worker

我希望每次加载页面时都向服务工作者发送消息。

第一次加载页面时调用register()然后侦听" controllerchange" navigator.serviceWorker上的事件,但这永远不会触发。

我如何知道何时可以开始postMessaging服务工作者?

navigator.serviceWorker.register(swURL).then(function(){
    var sw;

    if (navigator.serviceWorker.controller) {
        sw = navigator.serviceWorker.controller;
        sw.postMessage('ping');
        return;
    }

    function onchange(){
        sw = navigator.serviceWorker.controller;
        sw.postMessage('ping');
        navigator.serviceWorker.removeEventListener('controllerchange', onchange);
    }

    navigator.serviceWorker.addEventListener('controllerchange', onchange);
}).catch(function(err) {
    // registration failed :(
    console.log('ServiceWorker registration failed: ', err);
});

2 个答案:

答案 0 :(得分:1)

How do I know when I can start postMessaging a service worker?

Just focusing on that bit: I'd recommend the following approach, which makes use of the navigator.serviceWorker.ready promise:

// navigator.serviceWorker.ready can be used from anywhere in your
// page's JavaScript, at any time.
// It will wait until there's an active service worker, 
// and then resolve with the service worker registration
navigator.serviceWorker.ready.then(registration => {
  registration.active.postMessage('ping');
});

If you do want to get to the bottom of why your controllerchange event listener isn't firing, my guess would be that you're not using clients.claim() in your service worker's activate event, which means the newly-activated service worker won't take control of the current page.

答案 1 :(得分:1)

之所以无法启动,是因为您正在注册public class ServiceResponseAccessor { private CacheAccessor cacheAccessor; private String cacheKey; public ServiceResponseAccessor(String cacheKey) { this.cacheKey = cacheKey; } public String getCustomerId() { ServiceResponse response = cacheAccessor.get(cacheKey); return response.getCustomerId(); } public Preferences getCustomerPreferences() { ServiceResponse response = cacheAccessor.get(cacheKey); Customer customer = response.getCustomer(); if (customer == null) { throw new Exception("No Customer Preferences"); } return customer.getPreferences(); } } 事件之后,而Service Worker已安装/激活。因此,此事件将为 new 服务工作者触发,例如使用controllerchange的用户。但不适用于最初的Service Worker。

使用skipWaiting()承诺,只要检测到活动的Service Worker,它就会立即解决,无论何时安装/激活它。