Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。
由于javascript是单线程执行的,在求数列的过程中浏览器不能执行其它javascript脚本,UI渲染线程也会被挂起,从而导致浏览器进入僵死状态。使用web worker将数列的计算过程放入一个新线程里去执行将避免这种情况的出现
我的理解:有一个需要一段时间才能处理完的,可以采用此方法,新的线程。新的线程的运行不会堵塞主线程。仅此而已
WEB主线程:
1.通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。
2.通过worker.postMessage( data ) 方法来向worker发送数据。
3.绑定worker.onmessage方法来接收worker发送过来的数据。
4.可以使用 worker.terminate() 来终止一个worker的执行。
worker新线程:
1.通过postMessage( data ) 方法来向主线程发送数据。
2.绑定onmessage方法来接收主线程发送过来的数据。
看例子:
js/test/worker.js
onmessage =function (evt){
console.log("---"+evt.data);
var d = new Date();//通过evt.data获得发送来的数据
while(true){
}
console.log("---4444444444444");
postMessage( d );//将获取到的数据发送会主线程
//setTimeout(onmessage,2000);
}
1. onmessage
onmessage : 这个是一个方法,用来监听主线程发送的message。当然可以换成自定义名称,但是注意:如果主线程没有发送message,新的线程里面方法可以写成自定义,然后调用自定义
例如:L
MyMessage = funtion(){
};
MyMessage();
2. evt.data
主线程发送的信息,在新的线程中获取。如果主线程没有发送,这里会报错哦
3.while(true)
模拟新的线程正在执行很久的效果,此时主线程继续执行不影响。所以对主线程不堵塞
4. postMessage( d )
去掉while(true),将会执行发送信息,主线程就可以通过监听onmessage,获取到新线程传回的值
5.setTimeout()
主线程创建了新线程后,每隔两秒能通过onmessage获取到新线程返回的值
6. 新线程不能操作页面元素
主线程代码:index.html
<body>
<div id="start" class="content">start</div>
<div id="end" class="content">end</div>
<div id="tt"></div>
</body>
<script type="text/javascript" src="js/libs/jquery/jquery-1.12.4.js"></script>
<script>
var w = null;
$("#start").click(function () {
console.log("start");
if(w==null){
startWork();
}
});
$("#end").click(function () {
console.log("end");
if(w!=null){
stopWork();
}
});
var t = function () {
console.log("22222222");
}
setTimeout(t,2000)
//新线程
startWork = function () {
if(!!window.Worker){
w = new Worker("js/test/worker.js");
w.postMessage("hello world");
w.onmessage = function (e) {
$("#tt").html(e.data);
}
}
}
stopWork = function () {
w.terminate();
w=null;
}
startWork();
console.log("3456");
</script>
1. startWork();
创建一个新的线程,发送postMessage 一段话,然后监听onmessage 新线程传会的值,把值现在到页面上。
2. stopWork()
停止新线程
3.w.postMessage("hello world");
触发了新线程中的onmessage事件。如果没有w.postMessage,那么在新线程中,需要执行方法onmessage()或者执行自定义方法。
4. 执行结果
新线程while,不影响主线程打印3456和22222222