[TOC]

服务工作者线程可以拦截、重定向、修改页面发出的请求。

疑问

  • 第一次听说“工作者线程”,这是什么?

    • 二级子环境,用于与页面父环境并行执行js代码,但不能操作DOM API

      书摘&心得

  • JavaScript的单线程可以保证它与不同浏览器API兼容。

    • 如果支持多线程,那么像DOM这样的API就会出现问题。
  • 工作者线程的价值
    • 允许把主线程的工作转嫁给独立的实体,而不会改变现有的单线程模型。
  • JavaScript环境实际上是运行在托管操作系统中的虚拟环境。(就是宿主环境)
    • 在浏览器中每打开一个页面,就会分配一个它自己的环境。
    • 每个页面都有自己的内存、事件循环、DOM,等等。
    • 每个页面就相当于一个沙盒,不会干扰其他页面。
    • 浏览器同时管理多个环境是非常简单的,因为所有这些环境都是并行执行的。
  • 工作者线程
    • 原始页面环境之外、完全独立的二级子环境。
    • 能与依赖单线程交互的API(如DOM)互操作,但可以与父环境并行执行代码。
  • 创建工作流线程的开销很大,慎用

    工作者线程类型

  • 专用工作者线程

    • 工作者线程、Web Worker或Worker
    • 可以让脚本单独创建一个JavaScript线程,以执行委托的任务。
    • 只能被创建它的页面使用。
    • 在专用工作者线程内部,全局作用域是DedicatedWorkerGlobalScope的实例。
      • 因为这继承自WorkerGlobalScope,所以包含它的所有属性和方法。
      • 工作者线程可以通过self关键字访问该全局作用域。
  • 共享工作者线程
    • 类似专用工作者线程
    • 可以被多个不同的上下文使用,包括不同的页面。
  • 服务工作者线程

    • 用途是拦截、重定向和修改页面发出的请求
    • 充当网络请求的仲裁者的角色。

      专用工作者线程

      在行内创建工作者线程

      const blob = new Blob([
      `
      self.onmessage = ({ data, source }) => {
      console.log('service worker head:', data);
      source.postMessage('bar');
      };
      
      console.log(self, self.location);
      `,
      ]);
      const url = window.URL.createObjectURL(blob);
      const myWorker = new Worker(url);
      

      服务工作者线程

  • 涉及的内容极其广泛,几乎可以单独写一本书

    • image.png
  • 就其职能来看,是十分有潜力的技术
    • 比如批量修改请求的传参,或者批量修改接口返回的数据等等
  • 核心是网络缓存,通常用于制作离线应用。
  • 服务工作者线程应该也是通过self关键字访问全局作用域的。
  • 由于没有接触过类似需求/项目,这部分内容暂时不深入阅读。

    生命周期

  • 服务工作者线程可能存在的状态

    • 已解析(parsed)
      • 调用navigator.serviceWorker.register()会启动创建服务工作者线程实例的过程。
      • 刚创建的服务工作者线程实例会进入已解析状态。
    • 安装中(installing)
    • 已安装(installed)
      • 已安装状态是触发逻辑的好时机
      • 检查方式:
        • image.png
    • 激活中(activating)
    • 已激活(activated)
    • 已失效(redundant)
  • 状态的每次变化都会在ServiceWorker对象上触发statechange事件

    服务工作者线程消息

    客户端和service worker可以互通消息
    image.png

    拦截fetch事件

  • 拦截能力不限于fetch()方法发送的请求

  • 也能拦截对JavaScript、CSS、图片和HTML(包括对主HTML文档本身)等资源发送的请求。
  • 这些请求可以来自JavaScript,也可以通过