ServiceWorkerContainer.ready 为特定的 scriptURL 准备好了吗?
Posted
技术标签:
【中文标题】ServiceWorkerContainer.ready 为特定的 scriptURL 准备好了吗?【英文标题】:ServiceWorkerContainer.ready for a specific scriptURL? 【发布时间】:2016-02-29 16:25:59 【问题描述】:ServiceWorkerContainer.ready 解析为活动的 ServiceWorkerRegistration,但如果有多个服务工作者在运行(例如,来自上一页加载的服务工作者,同一页面中的多个注册),则它可以解析为多个服务工作者。当执行一段代码时,如何确保特定的 service worker 正在处理网络事件?
也就是怎么写一个函数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
);
【问题讨论】:
【参考方案1】:首先,请注意,每个作用域只能有一个活动的 Service Worker,并且您的客户端页面最多只能由一个且只有一个 Service Worker 控制。因此,当准备好解析时,您可以确定 控制您的页面 的服务人员处于活动状态。
要知道 任意 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();
;
);
)
希望对你有意义。
【讨论】:
我发现还有 a proposal 可以添加类似于 service worker 规范的内容。 我认为这不太正确:在activated
块内,还需要检查 e.target === navigator.serviceWorker.controller
: 在第一个页面加载时服务工作者将变得活跃(在某种意义上它已准备好从 some 页面接收功能事件),但它实际上不会控制注册它的页面,除非它调用 clients.claim()
。以上是关于ServiceWorkerContainer.ready 为特定的 scriptURL 准备好了吗?的主要内容,如果未能解决你的问题,请参考以下文章