在js页面中运行长耗时同步任务会导致页面假死影响用户体验
web worker是使得一个web应用程序可以在与主执行线程分离的后台线程中运行一个脚本操作,这样的好处是可以在一个单独的线程中执行费时的处理任务
它的作用是允许主线程创建worker线程,主线程与worker线程互不干扰,在worker线程结束后将结果返回给主线程
缺点
:worker一旦创建就会一直运行,不会被主线程的活动打断,所以用完要注意关闭
使用限制:
- 同源限制:worker线程执行脚本文件必须和主线程脚本文件同源
- 文件限制:worker线程无法读取本地文件,它所加载的脚本必须来自网络
- DOM操作限制:worker线程无法读取主线程所在页面的DOM对象,也不能过去
document、window
等对象,但是可以获取navigator、location、XMLHttpRequest、setTimeout
等浏览器API - 通信限制:worker线程不能直接和主线程通信,需要通过postMessage方法通信
- 脚本限制:不能执行alert、confirm,但可以发出ajax请求
简单示例:
var myWorker = new Worker('worker.js',{name:'myWorker'})
//worker.js
console.log(self.name)
复杂示例:worker线程向主线程发送消息,主线程接收;主线程向worker线程发送消息,不会终止worker与主线程正在进行的通信,而是实时接收
//主线程
<span id='app'></span>
<input id='msg' />
<button onclick="sendMsg()" />
<button onclick="stop()"/>
var w = new Worker('worker.js')
w.onmessage= ev=>{
document.getElementById('app').innnerHTML=ev.data
}
const sendMsg = ()=>{
w.postMessage(document.getElementById('msg').innerHTML)
}
const stop = ()=>{
w.terminate()
}
//worker线程
let i = 1
function simpleCount() {
i++
self.postMessage(i)
setTimeout(simpleCount, 1000)
}
simpleCount()
self.onmessage = ev => {
postMessage(ev.data + ' 呵呵~')
}
worker常用api:
- postMessage:主线程向worker线程发送消息,消息可以是任意类型数据
- terminate:主线程关闭worker线程
- onmessage:接收worker线程发送过来的消息
- onerror:worker线程发生错误的回调
worker线程中的全局对象为self,代表子线程自生,这是this指向self,其上有一些api:
- postMessage:worker线程向主线程发送消息
- close:worker线程自己关闭自己
- onmessage:接收主线程消息
- onerror:worker线程发生错误的回调
注意:w.postMessage
方法接受两个参数,第一个参数可以是任意数据类型,但是传递的是值引用;第二个参数是可选的Transferable对象的数组,用于传递所有权,如果一个对象所有权被转移,在发送它的上下文中将变为不可用,并且只有在它被发送到的worker中可用
worker线程中加载脚本:importScripts("script1.js")