前言
上篇文章(JS-初识-service worker线程)讲了service worker的简单用法,并且实现了断网缓存的功能。但是想要完全理解其中的代码,需要了解service worker的API及其API的设计原则。下面我们就一起来看看
serviceWorkerContainer对象
serviceWorkerContainer
对象用于service脚本的注册,并且通过navigator.serviceWorker
属性来访问。
我们来看一段上面文章的代码,(没有看上篇文章也不影响理解下面的代码):
navigator.serviceWorker.register('./sw.js')
.then(registration=>{
console.log('registe success');
})
通过navigator.serviceWorker
来得到serviceWorkerContainer
对象,然后调用对象上面的register
方法来注册service脚本。
register
方法返回一个期约,这个期约在脚本注册成功之后,会被解决为registration对象。
如果反复注册相同的service脚本,从第二次开始,
register
方法并不会执行任何动作。
要知道,并不是每个浏览器都支持service worker,所以我们需要在注册之前做属性检测
if( 'serviceWorker' in navigator ){
navigator.serviceWorker.register('./sw.js')
.then(registration=>{
console.log('registe success');
})
}
在注册service 脚本的时候,需要从服务器端加载脚本,这可能会影响其他资源的加载,增加了首页白屏的时间。所以我们只在其他资源加载完成之后,才去加载并注册脚本
完成的注册代码如下
if( 'serviceWorker' in navigator ){
window.addEventListener('load',()=>{
navigator.serviceWorker.register('./sw.js')
.then(registration=>{
console.log('registe success');
})
})
}
属性
ready:返回解决为registration的promise。当service脚本注册完成,该Promise就会得到解决
controller:返回与当前页面关联的激活状态的serviceWokrer
对象,如果没有激活状态的,就返回null
也就是说,可以通过
serviceWorkerContainer
对象直接访问serviceWokrer
对象
事件
serviceWorkerContainer
对象支持下面几个事件
- oncontrollerchange: 有新的service worker激活时,触发。即有新service线程控制client
- conerror:当service worker线程内部出项错误的时,触发
- onmessage: 当service worker线程向父级上下文发送消息时,触发
ServiceWorkerRegistration对象
serviceWorkerContainer
对象的register方法返回的期约,解决结果就是registration对象。每一个作用域都只有一个registration对象
属性
ServiceWorkerRegistration
对象有一个属性很是能说明这一点:
scope:返回service worker线程作用域完成的URL路径。也是service worker线程注册的唯一标识符。
其还有其他的属性:
- installing: 返回状态为installing的service worker线程,没有就返回null
- waiting:返回状态为waiting的service worker线程,没有就返回。waiting状态就是已安装(installed)的状态,等待着旧线程终止掉。
- active:返回状态为activating或者active状态的service worker线程,没有就返回null
这些属性表示可以直接访问
serviceWokrer
对像
事件
ServiceWorkerRegistration
对象支持一个事件:
onupdatefound:service worker线程有新版本安装的时候触发。
在sw脚本中oninstall事件和这个事件是同一时机触发的
方法
- showNotifications():通过notification对象向页面发送通知
- update():直接从服务中请求服务脚本,如果新脚本不同,则重新初始化。服务器可借着这个API来更新service的脚本
- unregister():注销service worker线程
serviceWorker对象
serviceWorker
对象是服务工作者本体。可以通过serviceWorkerContainer对象的contrller属性,或者ServiceWorkerRegistration
对象的active属性来获取
属性:
- scriptURL:注册时service worker线程完整的URL
- state:表示
serviceWorker
对象的状态
其状态有:installing,installed、activating、activate、activated、redundant
事件
onstatechange:在state发生变化的时候触发。
ServiceWorkerGlobalScope对象
最后一个也是相当重要的对象,这个对象是service worker线程所能访问的全局上下文。在编写service脚本的时候,很大程度上都要依靠这个对象
属性
- caches:返回cacheStorage对象
- clients:返回clients接口,用以访问Client对象
- registration:返回service worker线程的
ServiceWorkerRegistration
对象
通过
ServiceWorkerRegistration
对象,我们就可以拿到serviceWorker对象本身了
不知道大家有没有发现,我们无法直接获取
serviceWorker
对象,而是要通过其他对象的属性才能访问。这与专用工作者线程和共享工作者线程颇为不同。大家知道为什么吗
方法
- skipWaiting():这个方法可以强制性的让新版本线程跳过waiting状态,替换旧线程
- fetch():用来发送实际的网络请求
事件:
- install:在service worker线程进入安装状态触发
- activate:在service worker线程进入激活状态触发
与install相同触发时机的有,
ServiceWorkerRegistration
对象的onupdatefound事件与activate相同触发时机的有,
serviceWorkerContainer
对象的onchontrollerchange事件
- fetch:截获主页面的fetch请求时触发
- message:接收来自父级上下文的message时触发
总结:
这篇文章讲述了与service worker线程高度相关的对象,分别从属性,事件,方法,作用,地位这几个角度进行分析。看完这篇文章,上篇文章应该就能看得懂大概了,并且也能上手自己写一个service worker了。但还有对象的一些很重要的API,是关于通知和推送的。不过我没有写出来,虽说不难,但学习需要循序渐进嘛。
下篇文章我会讲service worker线程的生命周期(JS-service worker生命周期),理解了这个,会对整个service脚本的逻辑有个更整体的认识。