Web Worker技术
Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。
web worker 是运行在后台的 JavaScript,不会影响页面的性能。
1 用法
1.1 创建Web Worker
let worker = new Worker('workerJsFile.js')// 里面写在后台线程执行的js文件
1.2 onmessage方法
worker.onmessage()
用于监听 线程之间 的消息,一旦其中一方 调用 postMessage 方法发送消息,则另一方可通过 onmessage()
方法监听到,然后通过 event.data 参数获取到另一方发送的消息;
worker.onmessage()
处理函数允许我们在任何时刻,一旦接收到消息就可以执行一些代码,代码中消息本身作为事件的data属性进行使用;
1.3 postMessage方法
worker.postMessage()
用于在线程之间发送消息;
1.4 注意
- 在主线程中使用时,
onmessage()
和postMessage()
必须挂在worker对象上,而在worker中使用时不用这样做。原因是,在worker内部,worker是有效的全局作用域。 - 当一个消息在主线程和worker之间传递时,它被复制或者转移了,而不是共享。
1.5 terminate 方法
worker.terminate()
用于终止 worker
如果你需要从主线程中立刻终止一个运行中的worker,可以调用worker的terminate()
方法;
worker 线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作。
1.6 close 方法
而在worker线程中,workers 也可以调用自己的 close()
方法进行关闭
close()
2 demo
2.1 描述
在后台执行一个计时程序,计时到20停止,或者手动点击停止计时停止
2.2 主线程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<p>计数:<output id = "count"></output></p>
<button onclick="startWorker()">开始Worker</button>
<button onclick="stopWorker()">停止Worker</button>
<button onclick="resetCountTime(5)">重置计时时间</button>
</div>
</body>
</html>
<script>
let worker;
const startWorker = () => {
// 判断浏览器是否支持 Web Worker 属性
if (typeof Worker !== 'undefined') {
if (typeof worker == 'undefined') {
worker = new Worker('./workerDemo.js')
}
worker.onmessage = (event) => {
document.getElementById('count').innerHTML = event.data
}
} else {
document.getElementById('count').innerHTML = "浏览器不支持web worker属性"
}
}
const stopWorker = () => {
worker.terminate()
}
const resetCountTime = (count) => {
if (worker) {
worker.postMessage(count)
} else {
document.getElementById('count').innerHTML = "web worker 不存在"
}
}
</script>
2.3 worker线程
let count = 0
const oneSecond = 1000 //ms
const countTime = () => {
count++
console.log(count)
postMessage(count)
if (count > 10) {
// 自己终止后台线程
close()
}
setTimeout("countTime()", oneSecond)
}
countTime()
onmessage = (event) => {
count = event.data
}
2.4 演示:
3.引入脚本与库
Worker 线程能够访问一个全局函数importScripts()
来引入脚本,该函数接受0个或者多个URI作为参数来引入资源;以下例子都是合法的:
importScripts(); /* 什么都不引入 */
importScripts('foo.js'); /* 只引入 "foo.js" */
importScripts('foo.js', 'bar.js'); /* 引入两个脚本 */