今天看啥  ›  专栏  ›  三七二十一

webworker 使用实记

三七二十一  · 掘金  ·  · 2020-05-29 10:20
阅读 0

webworker 使用实记

在做一些大文件的批量上传时,需要计算文件的md5值,1G以上的文件计算时长可长达几秒,严重时会影响主线程的UI交互,因此使用webworker创建多线程计算md5,在主线程创建worker,在worker中计算md5,计算完成后关闭worker,并将结果返回给主线程。

webworker是什么

一个worker就是使用一个js脚本文件通过构造函数创建的一个对象,这个文件包含将在工作线程中运行的代码,这个对象供主线程操作 Worker。Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。

怎么用

1、创建js脚本文件 file.worker.js

// file.worker.js
onmessage = function (e) {
    // 处理数据
    console.log(e.date)
    
    if(e.date==='foo'){
        // 将结果返回主线程
        postMessage('bar')
        // 关闭worker
        close()
    }
}
复制代码

2、创建worker实例

// 主线程文件
import Worker from './file.worker'

const myWorker = new Worker()

// 主线程向worker发消息
myWorker.postMessage('foo')

// worker处理的结果返回给主线程
myWorker.onmessage = (e) => {
    console.log(e.data)
    // 关闭worker
    myWorker.terminate()
}


myWorker.onerror = (err) => {
  // 错误处理
}
复制代码

可以看出:

  • 1 无论是主线程还是worker线程均用postMessage发送消息,onmessage接受消息
  • 2 事件对象的data属性可以获取相互传送各种类型的数据
  • 3 为了节省系统资源,必须关闭 worker。主线程使用terminate();worker中使用close();

需要注意的一点是: 传递的数据是拷贝关系,即是传值而不是传址,Worker 对通信内容的修改,不会影响到主线程。事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给 Worker,后者再将它还原。>

这里插入一个遇到的浏览器bug: 在file.worker.js 中使用到File接口,在safari浏览器的一些稍低版本中,会报错:File is undefined,解决办法是使用Object.getPrototypeOf()返回file的原型。

const proto = File.prototype // 报错
const proto = Object.getPrototypeOf(file) // 正常
复制代码

参考:




原文地址:访问原文地址
快照地址: 访问文章快照