html5之webworker初识

本文转载自:http://www.cnblogs.com/feng_013/archive/2011/09/20/2175007.html

感谢博主!

Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面。

一:如何使用Worker

Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。

例子:

worker.js

// 绑定onmessage方法来接收主线程发送过来的数据
onmessage=function(e)
{
	var d = e.data;
	//通过postMessage( data ) 方法来向主线程发送数据
	postMessage(d)
}
webworker.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<link rel="stylesheet" href="./css/jquery-mobile.css">
		<script src="./js/jquery.js"></script>
		<script src="js/jquery-mobile.js"></script>
		<script type="application/javascript">
   			//加载一个JS文件来创建一个worker,同时返回一个worker实例
   			var worker = new Worker("./js/worker.js");
   			//通过worker.postMessage( data ) 方法来向worker发送数据
   			worker.postMessage("hello world");
   			//.绑定worker.onmessage方法来接收worker发送过来的数据
   			worker.onmessage = function(e)
   			{
   				console.log(e.data);
   			}
   			//可以使用 worker.terminate() 来终止一个worker的执行。
		</script>
	</head>
	<body>
	</body>
</html>
用Chrome浏览器打开html后,控制台输出  "hello world" 表示程序执行成功。

使用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方法来接收主线程发送过来的数据。

二:Worker能做什么

fibonacci数列被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*),而javascript的常用实现为: 

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

当n较大时浏览器直接提示脚本忙碌。

由于javascript是单线程执行的,在求数列的过程中浏览器不能执行其它javascript脚本,UI渲染线程也会被挂起,从而导致浏览器进入僵死状态。使用web worker将数列的计算过程放入一个新线程里去执行将避免这种情况的出现。具体看例子:

//fibonacci.js
var fibonacci =function(n) {
    return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
};
onmessage =function(event) {
    var n = parseInt(event.data, 10);
    postMessage(fibonacci(n));
};
<!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('fibonacci.js');  
      worker.addEventListener('message', function(event) {
        var timer2 = (new Date()).valueOf();
           console.log( '结果:'+event.data, '时间:'+ timer2, '用时:'+ ( timer2  - timer ) );
      }, false);
      var timer = (new Date()).valueOf();
      console.log('开始计算:40','时间:'+ timer );
      setTimeout(function(){
          console.log('定时器函数在计算数列时执行了', '时间:'+ (new Date()).valueOf() );
      },1000);
      worker.postMessage(40);
      console.log('我在计算数列的时候执行了', '时间:'+ (new Date()).valueOf() );
  }  
  </script>
</head>
<body>
</body>
</html>
结果:
开始计算:40 时间:1431523585185
fab.html (第 14 行)
我在计算数列的时候执行了 时间:1431523585188
fab.html (第 19 行)
定时器函数在计算数列时执行了 时间:1431523586188

这个例子说明在worker中执行的fibonacci数列的计算并不会影响到主线程的代码执行,完全在自己独立的线程中计算,只是在计算完成之后将结果发回主线程。

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


你可能感兴趣的:(html5之webworker初识)