HTML5---Web Worker
Web Worker
简介
JavaScript
执行是采用单线程进行执行的,通俗解释就是同一时间只能执行一件事,如果出现阻塞,那么后面代码就无法执行了;HTML5提出了Web Worker
标准,表示允许JavaScript
可以有多个进程,但子线程完全受主线程的控制,子线程不能操作 DOM,只有主线程可以操作 DOM,所以主线程为主的单线程执行原理形成了JavaScript
这门语言的核心.
Web Worker
简单来说就是在JavaScript
单线程执行的基础上,开启一个子线程,进行程序处理,从而不影响 主线程的执行,当子线程执行完毕,在回到主线程上,这个过程并不影响主线程执行过程.
传统处理中.执行以下代码,整页面都会被冻结,由于JavaScript
是单线程处理,如以下代码已经完全阻塞了后续的执行
while(true){}
换种方式.开启一个新进程来执行这段代码,将它放在一个单独的worker.js
文件中,在主线程中只需执行以下代码
var worker = new Worker("worker.js");
创建线程
在创建线程的时候需要给实例化的Worker
传入唯一一个参数,指向一个JavaScript
文件资源的 Url或者 Blob对象(Blob 对象是一个包含有只读原始数据类文件对象),调用这个构造函数后,一个线程就被创建了.如下:
var worker = new Worker("worker.js");
var worker = new Worker(blob);
线程通信
Web Worker
基本原理就是在当前的主线程中加载一个只读文件来创建一个新线程,两个线程同时存在,且互不阻塞,并且在子线程与主线程之间提供了数据交互的接口 postMessage
和onmessage
.来进行发送和接受数据.其数据格式可以为结构化数据(JSON
等);
两种方法来传输数据:
var worker = new Worker("worker.js")
//第一种传递方法
worker.postMessage(message,taransferList);
//第二种传递方法
worker.postMessage({
operation:"list_all_users",
input:buffer,
threshold:0.8,
},[buffer])
如果要想一个专用线程发送数据,那么我们需要使用线程中的 postMessage
方法。专用线程不仅仅支持传输二进制数据,也支持结构化的 JavaScript
数据格式。在这里有一点需要注意,为了高效地传输 ArrayBuffer
对象数据,需要在 postMessage
方法中的第二个参数中指定它。
同时我们如果需要接受某个线程传来的参数可以使用onmessage
//方法一
worker.onmessage = function(event){
var data = event.data;
}
//方法二
worker.addEventListener("message",target);
demo展示
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webWorker</title>
</head>
<body>
</body>
<script>
var worker = new Worker("worker.js");
worker.postMessage("发送信息");
worker.onmessage = function(e){
console.log(e.data);
}
</script>
</html>
worker.js
onmessage = function(e){
console.log(e.data) ;
postMessage("返回信息")
}
Worker 作用域
创建出一个新 worker
时,代码会运行在一个全新的JavaScript
环境中(WorkerGlobalScope
)运行,是完全和创建worker
的脚本隔离,这时我们可以把创建新worker
的脚本称之为主线程,而被创建的新的worker
叫做子线程.
WorkerGlobalScope
是 worker
的全局对象,所以它包含所有核心JavaScript
全局对象拥有的属性如 Json
等,window
的一些属性也拥有,类似 XMLHttpRequest()
等.
共享线程 SharedWorker
共享线程是为了避免线程的重复创建和销毁的过程,降低了系统性能的消耗,共享线程SharedWorker
可以同时有多个页面的线程链接.
使用SharedWorker
创建共享线程,也需要提供一个JavaScript
脚本文件的 URL 地址或 Blob,该脚本文件中包含了我们在线程中需要执行的代码
var worker = new SharedWorker("sharedWorker,js");
贡献线程也使用了message
事件监听线程消息,但使用SharedWorker
对象的port
属性与线程通信如下.
worker.port.onmessage = function(e){
...
}
同时我们也可以使用SharedWorker
对象的port
属性向共享线程发送消息如下.
worker.port.postMessage('message');
注:
- 如果采用 Chrome 运行,会报错
- image
- 原因是需要一个完整的域名,可以自己起一个 PHP 服务
- 或者采用 Firefox 测试