2016-02-29 28 views
2

ServiceWorkerContainer.ready解析为活动的ServiceWorkerRegistration,但如果存在多个服务工作人员(例如,来自上一页加载的服务工作人员,同一页面内的多个注册人员),则可以解析为多个服务工作人员。如何确保特定的服务人员在执行大量代码时处理网络事件?ServiceWorkerContainer.ready是否适用于特定的scriptURL?

也就是说,我怎么可以编写一个函数registerReady(scriptURL, options),可以使用如下:

registerReady("foo.js").then(function (r) { 
    // "foo.js" is active and r.active === navigator.serviceWorker.controller 
    fetch("/"); // uses foo.js's "fetch" handler 
}); 

registerReady("bar.js").then(function (r) { 
    // "bar.js" is active and r.active === navigator.serviceWorker.controller 
    fetch("/"); // use bar.js's "fetch" handler 
}); 

回答

2

首先,注意有可按每范围只有一个活动的服务工作人员和您的客户端页面可以通过控制最多也是唯一一名服务人员。因此,当准备好解决时,您肯定知道控制您的页面的服务工作人员处于活动状态。

要知道任意sw是否处于活动状态,您可以注册并检查注册中的服务工作人员队列,并监听其状态变化。例如:

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(); 
     } 
     }; 
    }); 
    }) 
} 

希望它对你有意义。

+0

我发现还有[提案](https://github.com/slightlyoff/ServiceWorker/issues/770)添加类似于服务工作者规范的东西。 – mjs

+0

我认为这不太正确:在'activated'块中,还需要检查e.target === navigator.serviceWorker.controller:在加载服务工作者的第一页上将变为活动状态(在它已经准备好从* some *页面接收函数事件了),但它实际上不会控制注册它的页面,除非它调用clients.claim()。 – mjs