如何使用JS中的webWorker

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

如何使⽤JS中的webWorker
⽬录
⼀、webWorker之初体验
⼆、webWorker之常⽤API
1、postMessage(data)
2、terminate()
3、message
4、error
三、worker上下⽂
四、关于worker
⼀、webWorker之初体验
所以,JavaScript是单线程也是有背景的。

如下:
<!DOCTYPE html>
<head>
<title>singleThread</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script>
//添加到任务队列中,待同步任务所处的‘执⾏栈'执⾏完毕,1秒后执⾏任务队列中的这个匿名函数
setTimeout(function(){
console.log('come on');
},1000);
//只要不关闭该alert,‘执⾏栈'就没结束,从⽽也就不会进⼊到任务队列中
alert('waiting');
</script>
</body>
</html>
但,HTML5引⼊了⼀个⼯作线程(webWorker)的概念。

它允许开发⼈员编写能够长时间运⾏⽽不被⽤户所中断的后台程序,去执⾏事务或者逻辑,并同时保证页⾯对⽤户的响应。

简⽽⾔之,就是允许JavaScript创建多个线程,但是⼦线程完全受主线程控制,且不得操作DOM。

从⽽,可以⽤webWorker来处理⼀些⽐较耗时的计算。

如下,主页⾯:
<!DOCTYPE html>
<head>
<title>worker</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script>
function init(){
//创建⼀个Worker对象,并向它传递将在新线程中执⾏的脚本url
var worker = new Worker('worker.js');
//接收worker传递过来的数据
worker.onmessage = function(event){
document.getElementById('result').innerHTML+=event.data+"<br/>" ;
};
};
</script>
</head>
<body onload = "init()">
<div id="result"></div>
</body>
</html>
下⾯是worker.js的内容:
var i = 0;
function timedCount(){
for(var j = 0, sum = 0; j < 100; j++){
for(var i = 0; i < 100000000; i++){
sum+=i;
};
};
//将得到的sum发送回主线程
postMessage(sum);
};
//将执⾏timedCount前的时间,通过postMessage发送回主线程
postMessage('Before computing, '+new Date());
timedCount();
//结束timedCount后,将结束时间发送回主线程
postMessage('After computing, ' +new Date());
上⾯代码执⾏的流程是:创建的worker对象,并⽤onmessage⽅法接收worker.js⾥⾯postMessage传递过来的数据(event.data),并将数据追加到div#result中。

所以,执⾏上⾯的代码结果如下:
图⼀
待worker.js中的timedCount⽅法运算完后,执⾏postMessage操作,向主线程传数据,得图⼆。

期间,并不影响主线程的运作。

图⼆
⼆、webWorker之常⽤API
接下来,再来看看关于worker的常⽤API:
1、postMessage(data)
⼦线程与主线程之间互相通信使⽤⽅法,传递的data为任意值。

//worker = new Worker('url');
//worker.postMessage传递给⼦线程数据,对象
worker.postMessage({first:1,second:2});
//⼦线程中也可以使⽤postMessage,如传递字符串
postMessage(‘test');
2、terminate()
主线程中终⽌worker,此后⽆法再利⽤其进⾏消息传递。

注意:⼀旦terminate后,⽆法重新启⽤,只能另外创建。

//worker = new Worker('url');
worker.terminate();
如,主页⾯:
<!DOCTYPE html>
<head>
<title>worker</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script>
function init(){
var worker = new Worker('worker.js');
//每隔100毫秒,向⼦线程传递{name: 'monkey'}信息
setInterval(function(){
worker.postMessage({name: 'monkey'});
},100);
//当主线程worker收到来⾃⼦线程的消息后,触发message事件
worker.onmessage = function(event){
document.getElementById('result').innerHTML+=event.data+"<br/>" ;
//主线程使⽤terminate⽅法中断与⼦线程来往,在浏览器中只能显⽰⼀次event.data
worker.terminate();
};
};
</script>
</head>
<body onload = "init()">
<div id="result"></div>
</body>
</html>
⼦线程worker.js代码:
//当主线程发来信息后,触发该message事件
onmessage = function(event){
//向主线程发送信息
postMessage();
};
3、message
当有消息发送时,触发该事件。

且,消息发送是双向的,消息内容可通过data来获取。

message使⽤,可见terminate中的demo
4、error
出错处理。

且错误消息可以通过e.message来获取。

如下:
//worker = new Worker('url');
worker.onerror = function(e){
//打印出错消息
console.log(e.message);
//中断与⼦线程的联系
worker.terminate();
}
另:worker线程从上到下同步运⾏它的代码,然后进⼊异步阶段来对事件及计时器响应,如果worker注册了message事件处理程序,只要其有可能触发,worker就⼀直在内存中,不会退出,所以通信完毕后得⼿动在主线程中terminate或者⼦线程中close掉,但如果worker没有监听消息,那么当所有任务执⾏完毕(包括计数器)后,他就会退出。

三、worker上下⽂
先看下⾯这段代码:
主页⾯:
<!DOCTYPE html>
<head>
<title>worker</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script>
function init(){
var worker = new Worker('worker.js');
//接收消息事件
worker.onmessage = function(event){
console.log(event.data);
};
//错误信息事件
worker.onerror = function(e){
console.log('erro: ' + e.message);
//终⽌线程
worker.terminate();
};
};
</script>
</head>
<body onload = "init()">
</body>
</html>
worker.js
//window对象的alert⽅法
alert(1);
onmessage = function(event){
//向主线程发送信息
postMessage();
};
执⾏上⾯代码结果:
为什么会这样呢?原因是alert为window对象的⽅法,所以会报错undefined。

worker.js执⾏的上下⽂,与主页⾯html执⾏时的上下⽂并不相同,最顶层的对象并不是window,woker.js执⾏的全局上下⽂,是个叫做WorkerGlobalScope的东东,所以⽆法访问window、与window相关的DOM API,但是可以与setTimeout、setInterval等协作。

WorkerGlobalScope作⽤域下的常⽤属性、⽅法如下:
1、self
我们可以使⽤ WorkerGlobalScope 的 self 属性来或者这个对象本⾝的引⽤
2、location
location 属性返回当线程被创建出来的时候与之关联的 WorkerLocation 对象,它表⽰⽤于初始化这个⼯作线程的脚步资源的绝对 URL,即使页⾯被多次重定向后,这个 URL 资源位置也不会改变。

3、close
关闭当前线程,与terminate作⽤类似
4、importScripts
我们可以通过importScripts()⽅法通过url在worker中加载库函数
5、XMLHttpRequest
有了它,才能发出Ajax请求
6、setTimeout/setInterval以及addEventListener/postMessage
四、关于worker
我们可以做什么:
1.可以加载⼀个JS进⾏⼤量的复杂计算⽽不挂起主进程,并通过postMessage,onmessage进⾏通信
2.可以在worker中通过importScripts(url)加载另外的脚本⽂件
3.可以使⽤setTimeout(), clearTimeout(), setInterval(), and clearInterval()
4.可以使⽤XMLHttpRequest来发送请求
5.可以访问navigator的部分属性
局限性:
1.不能跨域加载JS
2.worker内代码不能访问DOM
3.各个浏览器对Worker的实现不⼤⼀致,例如FF⾥允许worker中创建新的worker,⽽Chrome中就不⾏
4.IE这个新特性
以上就是浅谈webWorker的详细内容,更多关于浅谈webWorker的资料请关注其它相关⽂章!。

相关文档
最新文档