webWorker
背景
JS运是单线程的。但浏览器不是单线程的,可能存在js引擎线程、渲染线程、http请求线程等。
一旦出现 js【主线程】耗时操作,就会造成浏览器卡死,用户点击没响应等情况。
Web Worker 可以创建一个独立于主线程运行的子线程。可以将一些【可能会阻塞主线程的操作】,丢在 Worker 里去单独执行
简介
Web Worker 使得在一个独立于 Web 应用程序主执行线程的后台线程中运行脚本操作成为可能。这样做的好处是可以在独立线程中执行费时的处理任务,使主线程(通常是 UI 线程)的运行不会被阻塞/放慢。
Worker 类型
DedicatedWorkerGloabalScope : 用于专用 worker、只在当前页面使用
SharedWorkerGloabalScope: 共享 worker,多个页面共享(同域名)
Worker用法(DedicatedWorkerGloabalScope)
创建
- 在主线程中 通过 new Worker() 传入文件url来实现
- 返回 worker实例对象,该对象是主线程和其他线程的通讯桥梁
const myWorker = new Worker('worker.js')
接收消息
- 主线程通过 onmessage 接收子线程的消息
myWorker.onmessage = function(e){
//接收子线程消息
}
发送消息
- 主线程通过 postMessage 向子线程发送消息
myWorker.postMessage('Hello World!')
子线程接收、发送消息
//worker.js
self.postMessage(// 向主线程发送消息,主线程通过onmessage 接收)
self.onmessage = (e) => {
console.log('主线程发送过来的数据',e.data)
}
//还可以通过监听 message 事件来接收消息
self.addEventListener('message', function(e) {
console.log('收到消息:' + e.data);
})
终止
- terminate()
- close()
//主线程main.js
worker.terminate()
//子线程
self.close()
错误
- onerror
// 主线程中,监听 worker 错误
worker.onerror = (err) => {}
//子线程
self.onerror = (err) => {}
限制
- 同源限制
Worker 线程的文件必须与主线程的文件同源 - DOM 限制
Worker 线程不能直接操作 DOM - 通信限制
不再同一个上下文,不能直接通信,须通过 postMessage 、 onmessage完成 - 条数限制
浏览器能创建webworker线程 基本上都在20条以内,每条线程大概5M左右 - 文件限制
线程不能打开本地文件,只能打开网络文件
应用场景
大量的后台计算;
一般不会用到 worker,因为浏览器主线程很少会出现很复杂从而导致阻塞的操作。如果真的遇到了,可以用 worker 来创建一个子线程进行处理,提高用户体验