service worker有关的对象

885 阅读5分钟

前言

上篇文章(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对象支持下面几个事件

  1. oncontrollerchange: 有新的service worker激活时,触发。即有新service线程控制client
  2. conerror:当service worker线程内部出项错误的时,触发
  3. onmessage: 当service worker线程向父级上下文发送消息时,触发

ServiceWorkerRegistration对象

serviceWorkerContainer对象的register方法返回的期约,解决结果就是registration对象。每一个作用域都只有一个registration对象

属性

ServiceWorkerRegistration对象有一个属性很是能说明这一点:

scope:返回service worker线程作用域完成的URL路径。也是service worker线程注册的唯一标识符。

其还有其他的属性:

  1. installing: 返回状态为installing的service worker线程,没有就返回null
  2. waiting:返回状态为waiting的service worker线程,没有就返回。waiting状态就是已安装(installed)的状态,等待着旧线程终止掉。
  3. active:返回状态为activating或者active状态的service worker线程,没有就返回null

这些属性表示可以直接访问serviceWokrer对像

事件

ServiceWorkerRegistration对象支持一个事件:

onupdatefound:service worker线程有新版本安装的时候触发。

在sw脚本中oninstall事件和这个事件是同一时机触发的

方法

  1. showNotifications():通过notification对象向页面发送通知
  2. update():直接从服务中请求服务脚本,如果新脚本不同,则重新初始化。服务器可借着这个API来更新service的脚本
  3. unregister():注销service worker线程

serviceWorker对象

serviceWorker对象是服务工作者本体。可以通过serviceWorkerContainer对象的contrller属性,或者ServiceWorkerRegistration对象的active属性来获取

属性:

  1. scriptURL:注册时service worker线程完整的URL
  2. state:表示serviceWorker对象的状态

其状态有:installing,installed、activating、activate、activated、redundant

事件

onstatechange:在state发生变化的时候触发。

ServiceWorkerGlobalScope对象

最后一个也是相当重要的对象,这个对象是service worker线程所能访问的全局上下文。在编写service脚本的时候,很大程度上都要依靠这个对象

属性

  1. caches:返回cacheStorage对象
  2. clients:返回clients接口,用以访问Client对象
  3. registration:返回service worker线程的ServiceWorkerRegistration对象

通过ServiceWorkerRegistration对象,我们就可以拿到serviceWorker对象本身了

不知道大家有没有发现,我们无法直接获取serviceWorker对象,而是要通过其他对象的属性才能访问。这与专用工作者线程和共享工作者线程颇为不同。大家知道为什么吗

方法

  1. skipWaiting():这个方法可以强制性的让新版本线程跳过waiting状态,替换旧线程
  2. fetch():用来发送实际的网络请求

事件:

  1. install:在service worker线程进入安装状态触发
  2. activate:在service worker线程进入激活状态触发

与install相同触发时机的有,ServiceWorkerRegistration对象的onupdatefound事件

与activate相同触发时机的有,serviceWorkerContainer对象的onchontrollerchange事件

  1. fetch:截获主页面的fetch请求时触发
  2. message:接收来自父级上下文的message时触发

总结:

这篇文章讲述了与service worker线程高度相关的对象,分别从属性,事件,方法,作用,地位这几个角度进行分析。看完这篇文章,上篇文章应该就能看得懂大概了,并且也能上手自己写一个service worker了。但还有对象的一些很重要的API,是关于通知和推送的。不过我没有写出来,虽说不难,但学习需要循序渐进嘛。

下篇文章我会讲service worker线程的生命周期(JS-service worker生命周期),理解了这个,会对整个service脚本的逻辑有个更整体的认识。