引入web worker的原因
- JavaptScript采用的是单线程模式即所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没有做完,后面的任务只能等着。
- web worker的作用,就是为JavaScript创造多线程环境,允许主线程创建worker线程,将一些任务分配给后者运行。在主线程运行的同时,worker线程在后台运行,两者互不干扰。等到worker线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被worker线程负担了。主线程就会很流畅,不会被阻塞或拖慢。
- worker线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、表单提交)打断。这样有利于随时响应主线程通信。但是,这也造成worker比较耗费资源,不应该过度使用,而一旦使用完毕就应该关闭。
基本用法
- 在创建web worker之前,请检测用户的浏览器是否支持它:
if(typeof(Worker)!=="undefined")
{
//typeof(Worker):function
// 是的! Web worker 支持!
// 一些代码.....
}
else
{
//抱歉! Web Worker 不支持
}
- 创建web worker文件(在一个外部JavaScript中创建一个web worker)
- 创建web worker对象
从html页面调用web worker文件
下面的代码是检测是否存在worker对象,如果不存在,它会创建一个新的web worker对象,然后运行web worker文件
if(typeof(w)=="undefined")
{
w=new Worker("demo_workers.js");
}
Worker()构造函数的参数是一个脚本文件,该文件就是Worker线程所要执行的务。由于Worker不能读取本地文件,所以这个脚本必须来自网络。如果没有下载成功(比如404错误),Worker就会默默的失败。
w.postMessage()方法的参数,就是主线程传给Worker的数据。它可以是各种数据类型,包括二进制数据。接着主线程通过w.onmessage指定监听函数,接收子线程发回来的消息。
- 终止web worker
当创建web worker对象后,它会继续监听消息(即使在外部脚本完成之后)直到其被终止为止。终止web worker使用terminate()方法:
w.terminate();
完整的web worker实例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<p>计数: <output id="result"></output></p>
<button onclick="startWorker()">开始工作</button>
<button onclick="stopWorker()">停止工作</button>
<p><strong>注意:</strong> Internet Explorer 9 及更早 IE 版本浏览器不支持 Web Workers.</p>
<script>
var w;
function startWorker() {
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
w = new Worker("demo_workers.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "抱歉,你的浏览器不支持 Web Workers...";
}
}
function stopWorker()
{
w.terminate();
w = undefined;
}
</script>
</body>
</html>
参考教程
https://www.runoob.com/html/html5-webworkers.html
https://www.ruanyifeng.com/blog/2018/07/web-worker.html