- worker概述
- worker基本使用
- window下的postMessage
- worker多线程的应用
一、worker概述
web worker实际上是开启js异步执行的一种方式。在html5之前有事件、定时器、http请求三种异步机制,js本身并不能主动将一块代码使用异步的方式执行,worker的出现填补了js在非事件、定时器、http请求的情况下可以主动开启js代码的异步执行。worker有自己独立的线程,并非像前面三个异步机制那样的回调函数。所以,worker线程一旦建立成功,就会始终运行,并不会像前面三个异步机制那样被主线程打断,主线程与辅助线程(worker)之间通过消息事件通讯。
web worker相关手册与博客:
阮一峰网络日志:http://www.ruanyifeng.com/blog/2018/07/web-worker.html
MDN手册:https://developer.mozilla.org/zh-CN/docs/Web/API/Worker
developer博客:https://www.developer.com/lang/jscript/7-things-you-need-to-know-about-web-workers.html
上一篇博客的翻译版:https://blog.csdn.net/shenlei19911210/article/details/49779613
web worker使用注意事项:
1.同源限制:分配worker线程运行脚本文件,必须与主线程的脚本文件同源。
2.DOM限制:worker线程所在的全局对象,与主线程不一样,不能读取所在网页的DOM对象,也无法使用document 、 window 、parent这些对象。但是worker线程可以使用navigator对象和location对象。
3.通信联系:worker线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
4.脚本限制:worker线程不能执行alert()方法和cnfirm()方法,但可以使用XMLHttpRequest对象发送AJAX请求。
5.文件限制:worker线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本必须来自网络。
二、worker的基本使用
2.1在主线程中开启一个辅助线程:
var worker = new Worker('./worker.js'); //在主线程的中开启辅助线程(传入辅助线程的文件路径)
2.2主线程向辅助线程发送消息:
1 var data = {type:'sum',num:1000}//测试Function类型的值不能传递 2 worker.postMessage(data);//通过postMessage方法传递给辅助线程
2.3辅助线程接收主线程的消息:
1 this.onmessage = function(e){//在辅助线程中通过onmessage事件监听主线程postMessage发送过来的消息 2 console.log(e);//通过事件元对象中的data接收主线程发送过来的数据 3 console.log(e.data.num) 4 }
2.4.辅助线程向主线程提交工作(第5行代码):
1 this.onmessage = function(e){//在辅助线程中通过onmessage事件监听主线程postMessage发送过来的消息 2 var submitWorker = null; 3 if(e.data.type == 'sum'){ 4 submitWorker = sum(e.data.num); //辅助线程处理业务 5 this.postMessage(submitWorker); //辅助线程通过postMessage方法向主线程提交工作 6 } 7 } 8 function sum(num){ 9 var sumVal = 0; 10 for(var i = 0; i < num; i++){ 11 sumVal +=i; 12 } 13 return sumVal; 14 }
2.5主线程接收辅助线程的工作:
1 worker.onmessage = function(e){//主线程通过onmessage监听接收辅助线程的消息 2 console.log(e);// 同样通过事件元对象的data获取辅助线程传递过来的数据 3 console.log(e.data);//499500 4 }
2.6主线程辞退辅助线程与辅助线程主动关闭线程:
1 worker.terminate(); //主线程主动关闭辅助线程worker (辞退后不在接收辅助线程的消息) 2 this.close(); //辅助线程主动关闭线程(关闭后不再向主线程发送消息)
以上示例的全部代码,请注意需要在网络服务下测试,因为worker必须来自网络。
1 //indexWorker.html(主线程代码) 2 <!DOCTYPE html> 3 <html> 4 <head> 5 <meta charset="utf-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <title>worker</title> 8 <link rel="stylesheet" href=""> 9 </head> 10 <body> 11 <script> 12 var worker = new Worker('./worker.js'); 13 var data = { 14 type:'sum', 15 num:1000 16 } 17 worker.postMessage(data);//主线程向辅助线程发送消息 18 worker.onmessage = function(e){//主线程接收辅助线程的消息 19 console.log(e);// 同样通过事件元对象的data获取辅助线程传递过来的数据 20 console.log(e.data);//499500 21 // worker.terminate(); //主线程主动关闭辅助线程worker 22 } 23 24 </script> 25 </body> 26 </html> 27 28 //worker.js(辅助线程脚本代码) 29 this.onmessage = function(e){//在辅助线程中通过onmessage事件监听主线程postMessage发送过来的消息 30 // console.log(e);//通过事件元对象中的data接收主线程发送过来的数据 31 var submitWorker = null; 32 if(e.data.type == 'sum'){ 33 submitWorker = sum(e.data.num); //辅助线程处理业务 34 this.postMessage(submitWorker); //辅助线程通过postMessage方法向主线程提交工作 35 } 36 // this.close(); //辅助线程主动关闭线程(关闭后不再向主线程发送消息) 37 } 38 function sum(num){ 39 var sumVal = 0; 40 for(var i = 0; i < num; i++){ 41 sumVal +=i; 42 } 43 return sumVal; 44 }