# web worker

JavaScript实际上是运行在托管操作系统中的虚拟环境;浏览器中每打开一个界面,就会分配一个它自己的环境;每个页面就相当于一个沙盒,不会干扰其它界面;所有的这些环境都是并行执行的。

使用工作者线程,浏览器可以在原始页面环境之外再分配一个完全独立的二级子环境,这个子环境不能与依赖单线程交互的API(如DOM)互操作,但可以与父环境并行执行代码。

工作者线程,把计算量大的且持续的可以放在工作者线程上去处理。不过对node_modules不太友好,通常是需要放在静态目录下可以读取到的位置去处理,如static/public/assets等。

# 工作者线程的类型

有三种类型:专用工作者线程、共享工作者线程、服务工作者线程

  1. 专用工作者线程

通常简称为工作者线程、Web Worker或Worker,可以让脚本单独创建一个JavaScript线程,以执行委托任务;只能被创建它的页面使用

  1. 共享工作者线程

与专用工作者线程很相似,就是可以被多个不同的上下文使用,包括不同的页面;例如同源的脚本就可以向共享工作者线程发送消息或从中接收消息

  1. 服务工作者线程

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

  • 在引用的创建的webworker的实例引用的js里,使用self.importScripts引入需要使用的js
  • 创建一个Worker实例,postMessage发送信息,onmessage监听信息变化
this.worker = new Worker('/hash.js')
this.worker.postMessage({chunks:this.chunks})
this.worker.onmessage = e=>{
    const {progress,hash} = e.data
    this.hashProgress = Number(progress.toFixed(2))
    if(hash){
    resolve(hash)
    }
}
// 引入spark-md5

self.importScripts('spark-md5.min.js')


self.onmessage = e=>{
  // 接受主线程传递的数据
  const {chunks } = e.data
  const spark = new self.SparkMD5.ArrayBuffer()

  let progress = 0
  let count = 0

  const loadNext = index=>{
    const reader = new FileReader()
    reader.readAsArrayBuffer(chunks[index].file)
    reader.onload = e=>{
      count ++
      spark.append(e.target.result)

      if(count==chunks.length){
        self.postMessage({
          progress:100,
          hash:spark.end()
        })
      }else{
        progress += 100/chunks.length
        self.postMessage({
          progress
        })
        loadNext(count)
      }
    }
  }
  loadNext(0)
}
最后更新: 4/21/2022, 9:59:22 AM