多线程

来源:互联网 发布:nginx rtmp 直播配置 编辑:程序博客网 时间:2024/04/20 10:56

Web Workers基础知识

  

本章介绍HTML 5中新增的与线程相关的一个功能——使用Web Workers来实现Web平台上的多线程处理功能。通过Web Workers,你将可以创建一个不会影响前台处理的后台线程,并且在这个后台线程中创建多个子线程。通过Web Workers,你可以将耗时较长的处理交给后台线程去运行,从而解决了HTML 5之前因为某个处理耗时过长而跳出一个提示用户脚本运行时间过长,导致用户不得不结束这个处理的尴尬状况。

学习内容:

★ 掌握Web Workers的基本知识,能够使用Web Workers在Web网站或应用程序中创建一个后台线程。

★ 掌握在前台页面与后台线程进行数据交互时所使用到的方法与事件,能够在JavaScript脚本中实现前台页面与后台线程之间的数据交互。

★ 掌握在主线程之间嵌套子线程的方法,能够利用JavaScript脚本在主线程之中创建一个或多个子线程,能够实现主线程与子线程、子线程与子线程之间的数据传递。

★ 了解在后台线程中可以使用的JavaScript脚本中的对象、方法与事件。

Web Workers是在HTML 5中新增的,用来在Web应用程序中实现后台处理的一项技术。

在使用HTML 4与JavaScript创建出来的Web程序中,因为所有的处理都是在单线程内执行的,所以如果花费的时间比较长的话,程序界面会处于长时间没有响应的状态。最恶劣的是,当时间长到一定程度的话,浏览器还会跳出一个提示脚本运行时间过长的提示框,使用户不得不中断正在执行的处理。

为了解决这个问题,HTML 5新增了一个Web Workers API。使用这个API,用户可以很容易地创建在后台运行的线程(在HTML 5中被称为worker),如果将可能耗费较长时间的处理交给后台去执行的话,对用户在前台页面中执行的操作就完全没有影响了。

创建后台线程的步骤十分简单。只要在Worker类的构造器中,将需要在后台线程中执行的脚本文件的URL地址作为参数,然后创建Worker对象就可以了,如下例所示。

r worker=new Worker("worker.js"); 
 

但是,要注意在后台线程中是不能访问页面或窗口对象的。如果在后台线程的脚本文件中使用到window对象或document对象,则会引起错误的发生。

另外,可以通过发送和接收消息来与后台线程互相传递数据。通过对Worker对象的onmessage事件句柄的获取可以在后台线程之中接收消息,如下例所示。

worker.onme8sage=function(event) {     //处理收到的消息 } 


使用Worker对象的postMessage方法来对后台线程发送消息,如下例所示。发送的消息是文本数据,但也可以是任何JavaScript对象(需要通过JSON对象的stringify方法将其转换成文本数据)。

worker.postMessage(message); 


另外,同样可以通过获取Worker对象的onmessage事件句柄及Worker对象的postMessage方法在后台线程内部进行消息的接收和发送。

接下来,让我们看一个使用后台线程的示例。在该示例中,放置了一个文本框,用户在该文本框中输入数字,然后点击旁边的计算按钮,在后台计算从1到给定数值的合计值。虽然对于从1到给定数值的求和计算只需要用一个求和公式就可以了,但是本示例中为了展示后台线程的使用方法,采取了循环计算的方法。

首先,在示例1中,给出在HTML 4中的关于这个求和运算的示例代码。WANGYEXX.COM

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta charset="utf-8"> <script type="text/javascript"> function calculate()  {     var num = parseInt(document.getElementById("num").value, 10);     var result = 0;     //循环计算求和     for (var i = 0; i <= num; i++)      {       result += i;     }     alert("合计值为" + result + "。"); } </script> </head> <body> <h1>从1到给定数值的求和示例</h1> 输入数值:<input type="text" id="num"> <button onclick="calculate()">计算</button> </body> </html> 


执行这段代码的时候,在数值文本框中输入数值,在点击计算按钮之后,并在弹出合计值消息框之前,用户是不能在该页面上进行操作的。另外,虽然用户在文本框中输入比较小的值时,不会有什么问题,但是当用户在该文本框中输入100亿以上的值(这个值因不同浏览器而异)时,浏览器跳出一个如图1所示的提示脚本运行时间过长的对话框,导致用户不得不停止当前计算。

在HTML 5中,可以对以上示例重新书写,使用WebWorkers API让耗时较长的运算在后台运行,这样在上例的文本框中无论输入多么大的数值都可以正常运算了。示例2是对上例进行修改后的HTML 5中的代码。

<!DOCTYPE html> <head> <meta charset="UTF-8"> <script type="text/javascript"> // 创建执行运算的线程 var worker = new Worker("SumCalculate.js"); //接收从线程中传出的计算结果 worker.onmessage = function(event)  {     //消息文本放置在data属性中,可以是任何JavaScript对象.     alert("合计值为" + event.data + "。"); }; function calculate()  {     var num = parseInt(document.getElementById("num").value, 10);     //将数值传给线程     worker.postMessage(num); } </script> </head> <body> <h1>从1到给定数值的求和示例</h1> 输入数值:<input type="text" id="num"> <button onClick="calculate()">计算</button> </body> 


在这个示例中,把对于给定值的求和运算的处理放到了线程中单独执行,并且把线程代码单独书写在SumCalculate.js这个脚本文件中,示例3为这个脚本文件中的代码。

onmessage = function(event {     var num = event.data;     var result = 0;     for (var i = 0; i <= num; i++)      result += i;     //向线程创建源送回消息     postMessage(result); } 


这个求和运算的示例在Firefox 4、Safari 4、Google Chrome 3、Opera 1O浏览器中均能正常运行,在Firefox4中的运行结果如图2所示。

图2 WebWorkers API使用示例

原创粉丝点击