首页前端开发HTMLhtml5 多线程处理webWorker

html5 多线程处理webWorker

时间2024-01-26 17:06:03发布访客分类HTML浏览492
导读:收集整理的这篇文章主要介绍了html5教程-html5 多线程处理webWorker,觉得挺不错的,现在分享给大家,也给大家做个参考。小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 Web Wor...
收集整理的这篇文章主要介绍了html5教程-html5 多线程处理webWorker,觉得挺不错的,现在分享给大家,也给大家做个参考。小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

Web Worker提供了一个简单的方法使得 web 内容能够在后台运行脚本。一旦 worker 创建后,它可以向由它的创建者指定的事件监听函数传递消息,这样该 worker 生成的所有任务就都会接收到这些消息

worker 线程能够在不干扰 UI 的情况下执行任务。另外,它还能够使用 XMLHttPRequest (虽然 responseXML 与 channel 两个属性值始终是 null)来执行 I/O 操作。

生成 worker

创建一个新的 worker 十分简单。你所要做的就是调用 Worker() 构造函数,指定一个要在 worker 线程内运行的脚本的 URI,如果你希望能够收到 worker 的通知,可以将 worker 的 onmessage 属性设置成一个特定的事件处理函数。

 VAR myWorker = new Worker("my_task.js");
  myWorker.onmessage = function (oEvent) {
       console.LOG("Called back by the worker!/n");
 }
    ;
    

或者,你也可以使用 addEventListener()

 var myWorker = new Worker("my_task.js");
  myWorker.addEventListener("message", function (oEvent) {
       console.log("Called back by the worker!/n");
 }
    , false);
      myWorker.postMessage("");
     // start the worker.

例子中的第一行创建了一个新的 worker 线程。第三行为 worker 设置了 message 事件的监听函数。当 worker 调用自己的 postMessage() 函数时就会调用这个事件处理函数。最后,第七行启动了 worker 线程。

传递数据

在主页面与 worker 之间传递的数据是通过拷贝,而不是共享来完成的。传递给 worker 的对象需要经过序列化,接下来在另一端还需要反序列化。页面与 worker 不会共享同一个实例,最终的结果就是在每次通信结束时生成了数据的一个副本。大部分浏览器使用结构化拷贝来实现该特性。

实例:创建一个子线程来计算求和

     tITle>
    webWorkers 实例演示/title>
             请输入要求和的数:input tyPE="text" id="num">
    br>
         button onclick="caculate()">
    计算/button>
           script type="text/javascript">
             //1.创建计算的子线程         var worker = new Worker("worker1.js");
         function caculate(){
                 var num = parseint(document.querySelector('#num').value,10);
                 //2.将数据传递给子线程             worker.postMessage(num);
         }
           //3.从子线程接收处理结果并展示         worker.onmessage = function(event){
                 alert('总和为:'+ event.data);
         }
         /script>
    
script type="text/javascript"> //1.创建计算的子线程 var worker = new Worker("worker1.js"); function caculate(){ var num = parseInt(document.querySelector('#num').value,10); //2.将数据传递给子线程 worker.postMessage(num); } //3.从子线程接收处理结果并展示 worker.onmessage = function(event){ alert('总和为:'+ event.data); } /script>
 code class="hljs javascript">
onmessage = function(event){
         var result =0,     num  = event.data;
          for(var i = 1;
     i  num ;
i ++){
             result += i;
     }
         //向主线程返回消息     postMessage(result);
 }
    /code>

可以将比较耗时的处理交给一个后台线程,去处理,处理完之后将结果返回给主页面。

线程之间进行数据交互

线程间的数据交互是通过发送和接收消息来相互传递信息的,主线程首先创建Worker,通过Worker对象的postMessage方法,将数据传递给后台线程,而主程序通过onmessage 事件,或者自定义addEventListener 事件来监听后台返回后台线程处理的结果。同样,后台线程通过onmessage事件来接收主页面传递的数据,通过postMessage将处理结果返回给主页面。

实例:页面序随机产生100个数据,并将数据传递给后台线程过滤,将可以被3 整除的数据,返回给主页面,以动态表格的形式显示。

  

线程之间进行数据交互

 onmessage = function(event){
         var strNum = event.data;
         var numArr = strNum.split(";
    ");
         var returnNum = "";
         for(var i =0;
     i

线程间的嵌套

线程中可以嵌套子线程,这样可以把一个较大的后台线程切分成几个子线程,每个子线程格子完成相对独立的工作。

还是使用上述的实例,构造一个单层子线程嵌套的例子。把之前主页面生成随机数的工作放到后台线程,然后在后台线程中构造一个子线程,来挑选出可以被3整除的数据。传递的数据采用JSON的数据格式。

 !DOCTYPE html>
     head>
     meta charset="UTF-8">
     script type="text/javascript">
     var worker = new Worker("script.js");
     worker.postMessage("");
 // 从线程中取得计算结果 worker.onmessage = function(event) {
  if(event.data!="")  {
      var j;
     //行号  var k;
     //列号  var tr;
      var td;
      var intArray=event.data.split(";
    ");
      var table=document.getElementById("table");
      for(var i=0;
    iintArray.length;
i++)  {
      j=parseInt(i/10,0);
      k=i%10;
  if(k==0) //该行不存在  {
      //添加行  tr=document.createElement("tr");
      tr.id="tr"+j;
      table.appendChild(tr);
  }
  else //该行已存在  {
      //获取该行  tr=document.getElementById("tr"+j);
  }
      //添加列  td=document.createElement("td");
      tr.appendChild(td);
      //设置该列内容  td.innerHTML=intArray[j*10+k];
      //设置该列背景色  td.style.backgroundColor="blue";
      //设置该列字体颜色  td.style.color="white";
      //设置列宽  td.width="30";
  }
  }
 }
    ;
     /script>
     /head>
     body>
     h1>
    从随机生成的数字中抽取3的倍数并显示示例/h1>
     table id="table">
     /table>
     /body>

script.js子线程代码

 onmessage=function(event){
         var intArray=new Array(100);
        //随机数组     //生成100个随机数     for(var i=0;
    i100;
    i++)         intArray[i]=parseInt(Math.random()*100);
         var worker;
         //创建子线程     worker=new Worker("worker2.js");
         //把随机数组提交给子线程进行挑选工作     worker.postMessage(JSON.stringify(intArray));
     worker.onmessage = function(event) {
             //把挑选结果返回主页面         postMessage(event.data);
     }
 }
 

worker2.js代码

 onmessage = function(event) {
         //还原整数数组     var intArray= JSON.parse(event.data);
         var returnStr;
         returnStr="";
         for(var i=0;
i@H_695_126@

向子线程传递消息时,用worker.postMessage,向主页面提交数据时直接用postMessage.

多个子线程之间的数据交互

  

线程之间进行数据交互

worker1.js代码

 onmessage = function(event){
         var data = event.data;
         var dataArr = new Array(100);
         for(var i=0;
     i100;
 i++){
             dataArr[i] = parseInt(Math.random()*100);
     }
          //创建新的子进程     var worker2 = new Worker("worker3.js");
         //worker.postMessage传递JSON对象     worker2.postMessage(JSON.stringify(dataArr));
      worker2.onmessage = function(event){
             //postMessage将数据返回给主页面         postMessage(event.data);
     }
  }

worker3.js代码

 onmessage = function(event){
         var numArr = JSON.parse(event.data);
         var returnNum = "";
         for(var i =0;
     i

SharedWorker共享线程

共享线程
共享线程可以由两种方式来定义:一是通过指向 JavaScript 脚本资源的 URL 来创建,而是通过显式的名称。当由显式的名称来定义的时候,由创建这个共享线程的第一个页面中使用 URL 会被用来作为这个共享线程的 JavaScript 脚本资源 URL。通过这样一种方式,它允许同域中的多个应用程序使用同一个提供公共服务的共享线程,从而不需要所有的应用程序都去与这个提供公共服务的 URL 保持联系。

无论在什么情况下,共享线程的作用域或者是生效范围都是由创建它的域来定义的。因此,两个不同的站点(即域)使用相同的共享线程名称也不会冲突。

共享线程的创建
创建共享线程可以通过使用 SharedWorker() 构造函数来实现,这个构造函数使用 URL 作为第一个参数,即是指向 JavaScript 资源文件的 URL,同时,如果开发人员提供了第二个构造参数,那么这个参数将被用于作为这个共享线程的名称。创建共享线程的代码示例如下:

 var worker = new SharedWorker('sharedworker.js', ’ mysharedworker ’ );

与共享线程通信
共享线程的通信也是跟专用线程一样,是通过使用隐式的 MessagePort 对象实例来完成的。当使用 SharedWorker() 构造函数的时候,这个对象将通过一种引用的方式被返回回来。我们可以通过这个引用的 port 端口属性来与它进行通信。发送消息与接收消息的代码示例如下:

  // 从端口接收数据 , 包括文本数据以及结构化数据  worker.port.onmessage = function (event) {
 define your logic here... }
    ;
       // 向端口发送普通文本数据 worker.port.postMessage('put your message here … ');
   // 向端口发送结构化数据 worker.port.postMessage( {
     username: 'usertext';
  live_city:       ['data-one', 'data-two', 'data-three','data- four']}
    );
    

上面示例代码中,第一个我们使用 onmessage 事件处理器来接收消息,第二个使用 postMessage 来发送普通文本数据,第三个使用 postMessage 来发送结构化的数据,这里我们使用了 JSON 数据格式。

实例1:在单个页面中使用sharedWorker

  

单个页面的SharedWorker

 

script type="text/javascript"> var worker = new SharedWorker('test.js'); var p = document.querySelector('#show'); worker.port.onmessage = function(e){ p.innerHTML = e.data; } /script>
 onconnect = function(e){
         var port = e.ports[0];
         port.postMessage('你好!');
 }
     

实例2:在多个页面中使用sharedWorker

  
script type="text/javascript"> var worker; function window_onload(){ worker = new SharedWorker('test.js'); var p = document.getElementById('p1'); worker.port.addEventListener('message', function(e) { p.innerHTML=e.data; } , false); worker.port.start(); worker.port.postMessage(1); } /script>

在两个页面中共享后台线程

 

 onconnect = function(e) {
        var port = e.ports[0];
    port.onmessage = function(e) {
          port.postMessage(e.data*e.data);
    }
 }
     

只要发送不同的数据就可以worker.port.postMessage(1); 返回不同的结果。

实例3:在多个页面中,通过共享后台线程来共享数据

 meta charset="UTF-8">
     title>
    在多个页面中通过共享后台线程来共享数据/title>
     script type="text/javascript">
     var worker;
 function window_onload(){
         worker = new SharedWorker('test2.js');
         var p = document.getElementById('p1');
     worker.port.addEventListener('message', function(e) {
            document.getElementById("text").value=e.data;
     }
    , false);
         worker.port.start();
 }
 function SendData(){
         worker.port.postMessage(document.getElementById("text").value);
 }
 function getData(){
         worker.port.postMessage('get');
 }
     /script>
         h1>
    在多个页面中通过共享后台线程来共享数据/h1>
     input type="text" id="text">
     button onclick="SendData()">
    提交数据/button>
     button onclick="getData()">
    获取数据/button>
 onconnect = function(e) {
        var port = e.ports[0];
    port.onmessage = function(e) {
          port.postMessage(e.data*e.data);
    }
 }
     

在一个页面中点击发送数据,然后在另外一个页面点击接受数据,可以得到发送的数据。

Web Worker提供了一个简单的方法使得 web 内容能够在后台运行脚本。一旦 worker 创建后,它可以向由它的创建者指定的事件监听函数传递消息,这样该 worker 生成的所有任务就都会接收到这些消息

worker 线程能够在不干扰 UI 的情况下执行任务。另外,它还能够使用 XMLHttpRequest (虽然 responseXML 与 channel 两个属性值始终是 null)来执行 I/O 操作。

生成 worker

创建一个新的 worker 十分简单。你所要做的就是调用 Worker() 构造函数,指定一个要在 worker 线程内运行的脚本的 URI,如果你希望能够收到 worker 的通知,可以将 worker 的 onmessage 属性设置成一个特定的事件处理函数。

 var myWorker = new Worker("my_task.js");
  myWorker.onmessage = function (oEvent) {
       console.log("Called back by the worker!/n");
 }
    ;
    

或者,你也可以使用 addEventListener()

 var myWorker = new Worker("my_task.js");
  myWorker.addEventListener("message", function (oEvent) {
       console.log("Called back by the worker!/n");
 }
    , false);
      myWorker.postMessage("");
     // start the worker.

例子中的第一行创建了一个新的 worker 线程。第三行为 worker 设置了 message 事件的监听函数。当 worker 调用自己的 postMessage() 函数时就会调用这个事件处理函数。最后,第七行启动了 worker 线程。

传递数据

在主页面与 worker 之间传递的数据是通过拷贝,而不是共享来完成的。传递给 worker 的对象需要经过序列化,接下来在另一端还需要反序列化。页面与 worker 不会共享同一个实例,最终的结果就是在每次通信结束时生成了数据的一个副本。大部分浏览器使用结构化拷贝来实现该特性。

实例:创建一个子线程来计算求和

     title>
    webWorkers 实例演示/title>
             请输入要求和的数:input type="text" id="num">
    br>
         button onclick="caculate()">
    计算/button>
           script type="text/javascript">
             //1.创建计算的子线程         var worker = new Worker("worker1.js");
         function caculate(){
                 var num = parseInt(document.querySelector('#num').value,10);
                 //2.将数据传递给子线程             worker.postMessage(num);
         }
           //3.从子线程接收处理结果并展示         worker.onmessage = function(event){
                 alert('总和为:'+ event.data);
         }
         /script>
    
script type="text/javascript"> //1.创建计算的子线程 var worker = new Worker("worker1.js"); function caculate(){ var num = parseInt(document.querySelector('#num').value,10); //2.将数据传递给子线程 worker.postMessage(num); } //3.从子线程接收处理结果并展示 worker.onmessage = function(event){ alert('总和为:'+ event.data); } /script>
 code class="hljs javascript">
onmessage = function(event){
         var result =0,     num  = event.data;
          for(var i = 1;
     i  num ;
i ++){
             result += i;
     }
         //向主线程返回消息     postMessage(result);
 }
    /code>

可以将比较耗时的处理交给一个后台线程,去处理,处理完之后将结果返回给主页面。

线程之间进行数据交互

线程间的数据交互是通过发送和接收消息来相互传递信息的,主线程首先创建Worker,通过Worker对象的postMessage方法,将数据传递给后台线程,而主程序通过onmessage 事件,或者自定义addEventListener 事件来监听后台返回后台线程处理的结果。同样,后台线程通过onmessage事件来接收主页面传递的数据,通过postMessage将处理结果返回给主页面。

实例:页面序随机产生100个数据,并将数据传递给后台线程过滤,将可以被3 整除的数据,返回给主页面,以动态表格的形式显示。

  

线程之间进行数据交互

 onmessage = function(event){
         var strNum = event.data;
         var numArr = strNum.split(";
    ");
         var returnNum = "";
         for(var i =0;
     i

线程间的嵌套

线程中可以嵌套子线程,这样可以把一个较大的后台线程切分成几个子线程,每个子线程格子完成相对独立的工作。

还是使用上述的实例,构造一个单层子线程嵌套的例子。把之前主页面生成随机数的工作放到后台线程,然后在后台线程中构造一个子线程,来挑选出可以被3整除的数据。传递的数据采用JSON的数据格式。

 !DOCTYPE html>
     head>
     meta charset="UTF-8">
     script type="text/javascript">
     var worker = new Worker("script.js");
     worker.postMessage("");
 // 从线程中取得计算结果 worker.onmessage = function(event) {
  if(event.data!="")  {
      var j;
     //行号  var k;
     //列号  var tr;
      var td;
      var intArray=event.data.split(";
    ");
      var table=document.getElementById("table");
      for(var i=0;
    iintArray.length;
i++)  {
      j=parseInt(i/10,0);
      k=i%10;
  if(k==0) //该行不存在  {
      //添加行  tr=document.createElement("tr");
      tr.id="tr"+j;
      table.appendChild(tr);
  }
  else //该行已存在  {
      //获取该行  tr=document.getElementById("tr"+j);
  }
      //添加列  td=document.createElement("td");
      tr.appendChild(td);
      //设置该列内容  td.innerHTML=intArray[j*10+k];
      //设置该列背景色  td.style.backgroundColor="blue";
      //设置该列字体颜色  td.style.color="white";
      //设置列宽  td.width="30";
  }
  }
 }
    ;
     /script>
     /head>
     body>
     h1>
    从随机生成的数字中抽取3的倍数并显示示例/h1>
     table id="table">
     /table>
     /body>

script.js子线程代码

 onmessage=function(event){
         var intArray=new Array(100);
        //随机数组     //生成100个随机数     for(var i=0;
    i100;
    i++)         intArray[i]=parseInt(Math.random()*100);
         var worker;
         //创建子线程     worker=new Worker("worker2.js");
         //把随机数组提交给子线程进行挑选工作     worker.postMessage(JSON.stringify(intArray));
     worker.onmessage = function(event) {
             //把挑选结果返回主页面         postMessage(event.data);
     }
 }
 

worker2.js代码

 onmessage = function(event) {
         //还原整数数组     var intArray= JSON.parse(event.data);
         var returnStr;
         returnStr="";
         for(var i=0;
i

向子线程传递消息时,用worker.postMessage,向主页面提交数据时直接用postMessage.

多个子线程之间的数据交互

  

线程之间进行数据交互

worker1.js代码

 onmessage = function(event){
         var data = event.data;
         var dataArr = new Array(100);
         for(var i=0;
     i100;
 i++){
             dataArr[i] = parseInt(Math.random()*100);
     }
          //创建新的子进程     var worker2 = new Worker("worker3.js");
         //worker.postMessage传递JSON对象     worker2.postMessage(JSON.stringify(dataArr));
      worker2.onmessage = function(event){
             //postMessage将数据返回给主页面         postMessage(event.data);
     }
  }

worker3.js代码

 onmessage = function(event){
         var numArr = JSON.parse(event.data);
         var returnNum = "";
         for(var i =0;
     i

SharedWorker共享线程

共享线程
共享线程可以由两种方式来定义:一是通过指向 JavaScript 脚本资源的 URL 来创建,而是通过显式的名称。当由显式的名称来定义的时候,由创建这个共享线程的第一个页面中使用 URL 会被用来作为这个共享线程的 JavaScript 脚本资源 URL。通过这样一种方式,它允许同域中的多个应用程序使用同一个提供公共服务的共享线程,从而不需要所有的应用程序都去与这个提供公共服务的 URL 保持联系。

无论在什么情况下,共享线程的作用域或者是生效范围都是由创建它的域来定义的。因此,两个不同的站点(即域)使用相同的共享线程名称也不会冲突。

共享线程的创建
创建共享线程可以通过使用 SharedWorker() 构造函数来实现,这个构造函数使用 URL 作为第一个参数,即是指向 JavaScript 资源文件的 URL,同时,如果开发人员提供了第二个构造参数,那么这个参数将被用于作为这个共享线程的名称。创建共享线程的代码示例如下:

 var worker = new SharedWorker('sharedworker.js', ’ mysharedworker ’ );

与共享线程通信
共享线程的通信也是跟专用线程一样,是通过使用隐式的 MessagePort 对象实例来完成的。当使用 SharedWorker() 构造函数的时候,这个对象将通过一种引用的方式被返回回来。我们可以通过这个引用的 port 端口属性来与它进行通信。发送消息与接收消息的代码示例如下:

  // 从端口接收数据 , 包括文本数据以及结构化数据  worker.port.onmessage = function (event) {
 define your logic here... }
    ;
       // 向端口发送普通文本数据 worker.port.postMessage('put your message here … ');
   // 向端口发送结构化数据 worker.port.postMessage( {
     username: 'usertext';
  live_city:       ['data-one', 'data-two', 'data-three','data- four']}
    );
    

上面示例代码中,第一个我们使用 onmessage 事件处理器来接收消息,第二个使用 postMessage 来发送普通文本数据,第三个使用 postMessage 来发送结构化的数据,这里我们使用了 JSON 数据格式。

实例1:在单个页面中使用sharedWorker

  

单个页面的SharedWorker

 

script type="text/javascript"> var worker = new SharedWorker('test.js'); var p = document.querySelector('#show'); worker.port.onmessage = function(e){ p.innerHTML = e.data; } /script>
 onconnect = function(e){
         var port = e.ports[0];
         port.postMessage('你好!');
 }
     

实例2:在多个页面中使用sharedWorker

  
script type="text/javascript"> var worker; function window_onload(){ worker = new SharedWorker('test.js'); var p = document.getElementById('p1'); worker.port.addEventListener('message', function(e) { p.innerHTML=e.data; } , false); worker.port.start(); worker.port.postMessage(1); } /script>

在两个页面中共享后台线程

 

 onconnect = function(e) {
        var port = e.ports[0];
    port.onmessage = function(e) {
          port.postMessage(e.data*e.data);
    }
 }
     

只要发送不同的数据就可以worker.port.postMessage(1); 返回不同的结果。

实例3:在多个页面中,通过共享后台线程来共享数据

 meta charset="UTF-8">
     title>
    在多个页面中通过共享后台线程来共享数据/title>
     script type="text/javascript">
     var worker;
 function window_onload(){
         worker = new SharedWorker('test2.js');
         var p = document.getElementById('p1');
     worker.port.addEventListener('message', function(e) {
            document.getElementById("text").value=e.data;
     }
    , false);
         worker.port.start();
 }
 function SendData(){
         worker.port.postMessage(document.getElementById("text").value);
 }
 function getData(){
         worker.port.postMessage('get');
 }
     /script>
         h1>
    在多个页面中通过共享后台线程来共享数据/h1>
     input type="text" id="text">
     button onclick="SendData()">
    提交数据/button>
     button onclick="getData()">
    获取数据/button>
 onconnect = function(e) {
        var port = e.ports[0];
    port.onmessage = function(e) {
          port.postMessage(e.data*e.data);
    }
 }
     

在一个页面中点击发送数据,然后在另外一个页面点击接受数据,可以得到发送的数据。

觉得可用,就经常来吧! 欢迎评论哦! html5教程,巧夺天工,精雕玉琢。小宝典献丑了!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

ArrayClassdivDOMHTMLhtml5post-format-gallery数组

若转载请注明出处: html5 多线程处理webWorker
本文地址: https://pptw.com/jishu/587038.html
Html5 服务端推送 Server-Sent Event WebSocket 实战

游客 回复需填写必要信息