HTML5:使用web workers处理线程笔记

Web Workers概述

Web Workers的引入

Web Workers是HTML5提供的一种多线程机制。

线程的概念

线程是一个程序内的顺序控制流,使得一个程序具有能够“同时”执行多个任务的能力。线程可以认为是比程序更小的的可执行单元,实现了在程序内部并发执行多任务的能力。

Web Workers就是一种多线程机制,它本身考虑了线程安全问题,其底层是多线程技术。

<h1>Sum from 1 to n</h1>
<hr>
<label>Number:</label>
<input type="text" name="number1" id="number1"/>
<button onClick="calculate();">Computing</button>
<hr/>
Result:
<div id="result"></div>
<script>
    function calculate() {
       var num = parseInt(document.getElementById("number1").value, 10);
       var s = 1;
       for (var i = 1; i <= num; i++) {
          s += i;
        }
        document.getElementById("result").innerHTML = s;
    }
</script>

在这里插入图片描述

Web Workers

Web Workers是运行在后台的JavaScript,是HTML5实现多线程的一种方法,它的功能包括创建线程,线程与前端页面的数据交互,线程本身占用大量内存资源,本身也需要关闭或销毁。

Web Workers API中的方法和事件对上面的功能进行了封装。使用Web Workers API,用户可以很容易地创建在后台运行的线程(Worker),并完成数据交互和终止线程。

Web Workers API中常用的方法事件
在这里插入图片描述

使用Web Workers创建线程

创建线程的方法

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

var worker=new Worker("atask.js");

传递数据

通过发送和接收消息来实现前面页面与后台线程互相传递数据。接收消息的方法有2种。

通过获取Worker对象的onmessage事件的句柄可以在后台线程中接收消息。

worker.onmessage=function(event) {  
//消息处理,数据为event.data
} 

使用addEventListener()方法监听message事件。

work.addEventListener("message",function(event){
//document.getElementById(‘message’).innerHTML=e.data; 
//消息处理,数据为event.data   
},false);

如果想要发送消息,需要使用postMessage()方法。

<p>计算结果:
 <output id="result"></output>
</p>
<button onClick="startWorker()">开始Worker</button>
<button onClick="stopWorker()">结束Worker</button>
<script>
    var worker;
    function startWorker() {
    //创建web Worker,参数是需要执行的代码所在文件,该js应是耗时的操作。
     worker = new Worker("count.js");
        //接收消息
        worker.onmessage = function (e) {
             document.getElementById("result").innerHTML = e.data;
        };
    }
   function stopWorker() {
    //结束线程
       worker.terminate();
 }
</script>
var countNum = 0;
function count() {
    postMessage(countNum);
    countNum += 2;
    setTimeout(count, 1000);
}
count();

在这里插入图片描述

页面与线程数据的交互

页面和后台线程简单的文本数据交互

<h3>发送消息到Web Worker,并由Worker回应</h3>
<p>
     来自Worker的消息:
   <output id="message"></output>
</p>
<script>
 var worker = new Worker("work1.js");
 worker.onmessage = function(e) {
  document.getElementById("message").innerHTML = e.data;
 };
 worker.postMessage("YanHSama");
</script>
// JavaScript Document
self.addEventListener("message", function (e) {
    self.postMessage("Hello " + e.data);
}, false);

在这里插入图片描述

前台页面向后台传送JSON数据

<h3>发送消息到Web Worker,并由Worker回应</h3>
<p>
     来自Worker的消息:
   <output id="message"></output>
</p>
<script>
 var worker = new Worker("work2.js");
 worker.onmessage = function(e) {
  document.getElementById("message").innerHTML = e.data;
 };
 worker.postMessage({name: "YanHSama", age: 22});
</script>
// JavaScript Document
self.addEventListener("message", function (e) {
    self.postMessage("Hello " + e.data.name + "  ,U age is " + e.data.age);
}, false);

在这里插入图片描述

使用Web Worker改进

<h1>Sum from 1 to n</h1>
<hr>
<label>Number:</label>
<input type="text" name="number1" id="number1" />
<button onClick="calculate();">Computing</button>
<hr/> Result:
<output id="result"></output>
<script>
 var worker = new Worker("sum1.js");
 worker.onmessage = function(ee) { //事件监听,接收到数据后显示
  document.getElementById("result").innerHTML = ee.data;
 }
 function calculate() {
  var num = parseInt(document.getElementById("number1").value);
  worker.postMessage(num); //向后台线程发送数据
 }
</script>
// JavaScript Document
onmessage = function (aaa) {
    //error,alert(122);
    var num = aaa.data;
    //alert("third");
    var result = 0;
    //alert(num);
    for (var i = 1; i <= num; i++) {
        result += i;
    }
    postMessage(result);
}

在这里插入图片描述

使用ShareWorker创建共享线程

创建SharedWorker线程

创建SharedWorker线程的方法与前面创建Worker线程的方法类似,只是构造器略有区别。

var worker=new SharedWorker(url,[name]); 

传递数据

SharedWorker和Worker一样,可以实现前台页面与共享的后台线程之间的通信功能。创建SharedWorker对象时,也同时自动生成一个MessagePort对象。MessagePort对象包括下面的三个方法。

  • postMessage()方法:用于向另一个页面发送消息。
  • start()方法:用于激活端口,开始监听端口是否接收到消息。
  • close()方法:用于关闭并停用端口。

创建SharedWorker对象和发送消息

每个MessagePort对象都具有一个onmessage事件,当端口接收到消息时触发该事件。可以通过MessagePort对象的postMessage()方法,从端口向共享的后台线程发送消息,代码如下。

var worker=new SharedWorker(url, [name]);
var port=worker.port;
port.postMessage(message);

接收消息

第1种方法,通过对port对象的onmessage事件句柄的获取可以在后台线程中接收消息.

port.onmessage=function(event) {   
//消息处理
}

第2种方法,使用addEventListener()方法对message事件进行监听。

port.addEventListener("message",fuction(e){
//document.getElementById("message").innerHTML = e.data;
//消息处理
},false);

connect事件

前台页面通过SharedWorker对象与共享的后台线程开始通信时,会触发后台线程对象的onconnect事件,监听该事件,并且在后台脚本中定义该事件触发时所做的处理,这就是SharedWorker的线程处理代码。connect事件监听的代码描述如下:

onconnect = function (event) { 
//定义事件处理函数
}

使用ShareWorker的例子

<h3>生成n位验证码</h3>
<hr/>
验证码位数:<input type="text" name="num"><br/>
<button onClick="Generate()">生成</button>
<br/>
生成的验证码是:
<output id="result"></output>
<script>
 var worker;
 function Generate() {
  worker = new SharedWorker("gen.js");
  var num = document.getElementsByName("num")[0].value;
  worker.port.onmessage = function(e) {
   document.getElementById("result").innerHTML = e.data;
  }
  worker.port.start();
  worker.port.postMessage(parseInt(num));
 }
</script>
// JavaScript Document
onconnect = function (e) {
    var port = e.ports[0];
    port.onmessage = function (e) {
        var letterData = "";
        var chars = new Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "g", "k", "l", "m", "n", "o", "p", "z", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6");
        var num = e.data;
        for (var i = 0; i < num; i++) {
            var index = Math.floor(Math.random() * chars.length);
            var letter = chars[index];
            letterData += letter;
        }
        port.postMessage(letterData);
    }
}

在这里插入图片描述

使用ShareWorker共享数据

<script>
 var worker;
 //init()方法用于初始化SharedWorker,开始监听端口是否接收到消息
 //在body的onload事件中加载
 function init() {
  worker = new SharedWorker("gen2.js");
  worker.port.onmessage = function(e) {
   document.getElementById("result").innerHTML = e.data;
  }
  worker.port.start();
 }
 SharedWorker
 //向SharedWorker提交信息
 function postN() {
  var num = document.getElementsByName("num")[0].value;
  worker.port.postMessage(parseInt(num));
 }
 //获取验证码信息,使用共享标记'get'
 function getN() {
  worker.port.postMessage('get');
 }
</script>
<body onLoad="init()">
<h3>生成n位验证码</h3>
<hr/>
验证码位数:<input type="text" name="num"><br/>
<input type="submit" value="提交数字" onClick="postN()"/>
<input type="submit" value="获取验证码" onClick="getN()"/><br/>
生成的验证码是:
<output id="result"></output>
 </body>
// JavaScript Document
var letterdata = "";  //验证码变量
onconnect = function (e) {
    var port = e.ports[0];
    port.onmessage = function (e) {
        //验证码生成器种子
        var chars = new Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "g", "k", "l", "m", "n", "o", "p", "z", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6");
        var num;
        //以下是共享关键代码,主要通过get识别
        if (e.data == "get")
            port.postMessage(letterdata);
        else {
            num = e.data;
            for (var i = 0; i < num; i++) {
                var index = Math.floor(Math.random() * chars.length);
                var letter = chars[index];
                letterdata += letter;
            }
            //port.postMessage(letterdata);
        }
    }
}

在这里插入图片描述

发布了137 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_40119412/article/details/104159424