HTML5新特性之工作线程Web Worker

一、Web Worker的起因:

众所周知,在HTML5推出之前的 JavaScript 的运行都是以单线程的方式工作的,虽然有多种方式实现了对多线程的模拟

(例如:JavaScript 中的 setinterval 方法,setTimeout 方法等),但是在本质上程序的运行仍然是由 JavaScript 引擎以单线

程调度的方式进行的。单线程的不足就是效率低下。HTML5 中引入工作线程使得浏览器端的 JavaScript 引擎可以并发地执行

JavaScript 代码,实现了对浏览器端多线程编程的良好支持。从而提升处理效率。

引申:什么是线程,什么是进程。区别是什么?

进程我喜欢比喻成一个工厂,那么进程就是工厂中的员工。一个工厂可以有多名员工。也就是说一个进程里可以有多条线程。

在多线程中需要注意的是,进程中的各个线程是共享整个进程资源的,不过有些资源的容量有限,比如工厂的洗手间。这时候就

需要一种机制来进行维护。那就是利用“互斥锁”来完成。它的实现原理好比将进门的钥匙挂在门上,有线程进入这个资源就取走一

片钥匙,如果没有钥匙就无法进入房间,也就是说此资源共享容量已满。其中又会出现一些问题比如“死锁”,这里就不做延伸了。

想了解的朋友可以看:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html


二、Web Worker的使用:

Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到

互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。

具体实例:

①HTML页面:test.html

<!DOCTYPE HTML>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <script type="text/javascript">
     //WEB页主线程
     var worker =new Worker("worker.js"); 
    //创建一个Worker对象并向它传递将在新线程中执行的脚本的URL
    worker.postMessage("hello world");     
    //向worker发送数据
    worker.onmessage =function(evt){     
       //接收worker传过来的数据函数
       console.log(evt.data);              
      //输出worker发送来的数据
    }
 </script>
 </head>
 <body></body>
</html>
②js页面:woker.js

//worker.js
onmessage =function (evt){
  var d = evt.data;
  //通过evt.data获得发送来的数据
  postMessage( d );
  //将获取到的数据发送会主线程
}
浏览器打开将在控制台输出
hello world
由上可以看出使用Web Worker主要分为以下几部分:

WEB主线程:

1.创建Worker,使用worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。

2.发送数据。通过worker.postMessage( data ) 方法来向worker发送数据。

3.接收数据。绑定worker.onmessage方法来接收worker发送过来的数据。

4.终止Worker。使用worker.terminate() 来终止一个worker的执行。(后面将使用)

Worker新线程(也就是上面的worker.js):

1.发送数据,通过postMessage( data ) 方法来向主线程发送数据。

2.接收数据,绑定onmessage方法来接收主线程发送过来的数据。


三、Web Worker能解决什么问题:

大家知道在数学上,斐波那契数列被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*),

也是就是兔子生兔子的数列,而javascript的常用实现为:

 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>
 </head>
 <body>
  <script>
		var fibonacci =function(n) {
    		return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
		};
		var timerStart = (new Date()).valueOf();
		fibonacci(40);
		var timerEnd = (new Date()).valueOf();
		var timer = timerEnd - timerStart;
		console.log('No Web Worker的时间为:'+timer);
  </script>
 </body>
</html>

最后运行的结果:


由于javascript是单线程执行,在求数列的过程中浏览器不能执行其它javascript脚本,UI渲染线程也会被挂起,从而

导致浏览器进入僵死状态。使用web worker将数列的计算过程放入一个新线程里去执行将避免这种情况的出现。

具体看例子:

①HTML页面:fibonacci.html页面:

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>web worker fibonacci</title>
    <script type="text/javascript">
        onload =function(){
            var worker =new Worker('worker.js');
            worker.addEventListener('message', function(event) {
                var timer2 = (new Date()).valueOf();
                console.log( 'Web Worker用时:'+ ( timer2  - timer ) );
            }, false);
            var timer = (new Date()).valueOf();
            worker.postMessage(40);
        }
    </script>
</head>
<body>
</body>
</html>

②js页面worker.js:

var fibonacci =function(n) {
    return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
};
self.onmessage =function(event) {
    postMessage(fibonacci(event.data));
}

最后结果如下:


对比发现worker的效率要高,这个也例子说明在worker中执行的fibonacci数列的计算并不会影响到主线程的代码执行

,完全在自己独立的线程中计算,只是在计算完成之后将结果发回主线程。利用web worker我们可以在前端执行一些复杂

的大量运算而不会影响页面的展示,并且不会弹出恶心的脚本正忙提示。


四、总结:

web 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).不是每个浏览器都支持这个新特性


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值