Heim > Web-Frontend > H5-Tutorial > HTML5-Multithreading-WebWorker

HTML5-Multithreading-WebWorker

黄舟
Freigeben: 2017-02-16 14:21:47
Original
1711 Leute haben es durchsucht

Web Worker

Web Worker bietet eine einfache Möglichkeit, Webinhalten die Ausführung von Skripts im Hintergrund zu ermöglichen. Sobald ein Worker erstellt wurde, kann er Nachrichten an die von seinem Ersteller angegebene Ereignis-Listener-Funktion weiterleiten, sodass alle vom Worker generierten Aufgaben diese Nachrichten empfangen.

Der Worker-Thread kann Nachrichten weiterleiten, ohne die Benutzeroberfläche zu beeinträchtigen Aufgaben. Darüber hinaus kann es auch XMLHttpRequest verwenden (obwohl die Attributwerte „responseXML“ und „channel“ immer null sind), um E/A-Vorgänge auszuführen.

Arbeiter generieren

Das Erstellen eines neuen Arbeiters ist sehr einfach. Sie müssen lediglich den Worker()-Konstruktor aufrufen und den URI eines Skripts angeben, das im Worker-Thread ausgeführt werden soll. Wenn Sie vom Worker benachrichtigt werden möchten, können Sie das onmessage-Attribut des Workers auf einen bestimmten Ereignishandler festlegen.

var myWorker = new Worker("my_task.js");

myWorker.onmessage = function (oEvent) {
  console.log("Called back by the worker!\n");
};
Nach dem Login kopieren
Nach dem Login kopieren

Alternativ können Sie addEventListener() verwenden:

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.
Nach dem Login kopieren
Nach dem Login kopieren

Die erste Zeile im Beispiel erstellt einen neuen Arbeitsthread. Die dritte Zeile legt die Listener-Funktion für das Nachrichtenereignis auf dem Worker fest. Dieser Ereignishandler wird aufgerufen, wenn der Worker seine eigene postMessage()-Funktion aufruft. Schließlich startet Zeile 7 den Worker-Thread.

Daten übertragen

Die zwischen der Hauptseite und dem Arbeiter übertragenen Daten werden durch Kopieren statt Teilen abgeschlossen. An Arbeiter übergebene Objekte müssen am anderen Ende serialisiert und dann deserialisiert werden. Die Seite und der Worker nutzen nicht dieselbe Instanz und das Endergebnis ist, dass am Ende jeder Kommunikation eine Kopie der Daten generiert wird. Die meisten Browser verwenden strukturierte Kopien, um diese Funktion zu implementieren.

Beispiel: Erstellen Sie einen Sub-Thread, um die Summe zu berechnen

<!DOCTYPE html><html><head>
    <title>webWorkers 实例演示</title></head><body>
    请输入要求和的数:<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(&#39;#num&#39;).value,10);            //2.将数据传递给子线程
            worker.postMessage(num);
        }        //3.从子线程接收处理结果并展示
        worker.onmessage = function(event){
            alert(&#39;总和为:&#39;+ event.data);
        }    </script></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onmessage = function(event){
    var result =0,
    num  = event.data;    for(var i = 1; i < num ;i ++){
        result += i;
    }    //向主线程返回消息
    postMessage(result);
}
Nach dem Login kopieren
Nach dem Login kopieren

Sie können zeitaufwändige Verarbeitung zur Verarbeitung an einen Hintergrund-Thread übergeben, Nach der Verarbeitung werden die Ergebnisse an die Hauptseite zurückgegeben.

HTML5-Multithreading-WebWorker

Dateninteraktion zwischen Threads

Dateninteraktion zwischen Threads überträgt Informationen untereinander durch Senden und Empfangen von Nachrichten Der Hauptthread erstellt zunächst einen Worker und übergeben Sie die Daten über die postMessage-Methode des Worker-Objekts an den Hintergrund-Thread. Das Hauptprogramm lauscht dem Hintergrund und gibt die Ergebnisse der Hintergrund-Thread-Verarbeitung über das Ereignis onmessage oder ein benutzerdefiniertes addEventListener-Ereignis zurück. In ähnlicher Weise empfängt der Hintergrundthread die von der Hauptseite über das Ereignis onmessage übergebenen Daten und gibt die Verarbeitungsergebnisse über postMessage an die Hauptseite zurück.

Beispiel: Die Seitensequenz generiert zufällig 100 Daten und übergibt die Daten zum Filtern an den Hintergrundthread. Die durch 3 teilbaren Daten werden an die Hauptseite zurückgegeben und in Form von angezeigt eine dynamische Tabelle.

<!DOCTYPE html><html><head>
    <title>线程之间进行数据交互</title></head><body>
    <h2>线程之间进行数据交互</h2>
    <table id="table" style="color: #FFF;background-color: #ccc;">

    </table></body>
    <script type="text/javascript">
        var nums = new Array(100),
        intStr = "";        //1.处理非字符串数据
        for(var i = 0; i<100; i++){
            nums[i] = parseInt(Math.random()*100);
            intStr += nums[i] + ";";
        }        //2.创建新进程
        var worker = new Worker("worker2.js");        //3.向子进程发送数据
        worker.postMessage(intStr);        //4.从子线程获取处理结果
        worker.onmessage = function(event){
            var row,
                col,
                tr,
                td,
                table = document.querySelector("#table");            var numArr = event.data.split(";");            for(var i = 0; i<numArr.length; i++){
                row = parseInt(i/10);
                col = i%10;                if (col == 0 ) {
                    tr = document.createElement("tr");
                    tr.id = "tr" + row;
                    table.appendChild(tr);
                }else{
                    tr = document.querySelector("#tr" + row);
                }
                td = document.createElement(&#39;td&#39;);
                tr.appendChild(td);
                td.innerHTML = numArr[i];
                td.width = "30";
            }
        }    </script></html>
Nach dem Login kopieren
Nach dem Login kopieren
onmessage = function(event){
    var strNum = event.data;    var numArr = strNum.split(";");    var returnNum = "";    for(var i =0; i<numArr.length; i++){        if (numArr[i]%3 ==0) {
            returnNum += numArr[i] + ";";
        }
    }
    postMessage(returnNum);

}
Nach dem Login kopieren
Nach dem Login kopieren

HTML5-Multithreading-WebWorker

Verschachtelung zwischen Threads

Unterthreads können in Threads verschachtelt werden, sodass ein größerer Hintergrundthread geschnitten werden kann Mehrere Unterthreads, jedes Unterthread-Gitter vervollständigt relativ unabhängige Arbeiten.

Konstruieren Sie weiterhin unter Verwendung des obigen Beispiels ein Beispiel für die Verschachtelung einschichtiger Sub-Threads. Platzieren Sie die vorherige Arbeit zum Generieren von Zufallszahlen auf der Hauptseite in einem Hintergrundthread und erstellen Sie dann einen Unterthread im Hintergrundthread, um Daten auszuwählen, die durch 3 geteilt werden können. Die übergebenen Daten liegen im JSON-Datenformat vor.

<!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;i<intArray.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>
Nach dem Login kopieren
Nach dem Login kopieren

script.js-Sub-Thread-Code

onmessage=function(event){
    var intArray=new Array(100);    //随机数组
    //生成100个随机数
    for(var i=0;i<100;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);
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

worker2.js-Code

onmessage = function(event) {
    //还原整数数组
    var intArray= JSON.parse(event.data);    var returnStr;
    returnStr="";    for(var i=0;i<intArray.length;i++)
    {        //能否被3整除
        if(parseInt(intArray[i])%3==0)    
        {            if(returnStr!="")
                returnStr+=";";            //将能被3整除的数字拼接成字符串
            returnStr+=intArray[i];    
        }
    }    //返回拼接字符串
    postMessage(returnStr); 
    //关闭子线程          
    close();                         
}
Nach dem Login kopieren
Nach dem Login kopieren

HTML5-Multithreading-WebWorker

Verwenden Sie bei der Übermittlung von Nachrichten an Unterthreads worker.postMessage. Wenn Sie Daten an die Hauptseite senden, verwenden Sie postMessage direkt.

Dateninteraktion zwischen mehreren Unterthreads

<!DOCTYPE html><html><head>
    <title>线程之间进行数据交互</title></head><body>
    <h2>线程之间进行数据交互</h2>
    <table id="table" style="color: #FFF;background-color: #ccc;">

    </table></body>
    <script type="text/javascript">

        var worker1 = new Worker("worker1.js");
        worker1.postMessage("");        //从子线程获取处理结果
        worker1.onmessage = function(event){
            var row,
                col,
                tr,
                td,
                table = document.querySelector("#table");            var numArr = event.data.split(";");            for(var i = 0; i<numArr.length; i++){
                row = parseInt(i/10);
                col = i%10;                if (col == 0 ) {
                    tr = document.createElement("tr");
                    tr.id = "tr" + row;
                    table.appendChild(tr);
                }else{
                    tr = document.querySelector("#tr" + row);
                }
                td = document.createElement(&#39;td&#39;);
                tr.appendChild(td);
                td.innerHTML = numArr[i];
                td.width = "30";
            }
        }    </script></html>
Nach dem Login kopieren
Nach dem Login kopieren

worker1.js-Code

onmessage = function(event){
    var data = event.data;    var dataArr = new Array(100);    for(var i=0; i<100; 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);
    }

}
Nach dem Login kopieren
Nach dem Login kopieren

worker3.js-Code

onmessage = function(event){
    var numArr = JSON.parse(event.data);    var returnNum = "";    for(var i =0; i<numArr.length; i++){        if (numArr[i]%3 ==0) {
            returnNum += numArr[i] + ";";
        }
    }
    postMessage(returnNum);

}
Nach dem Login kopieren
Nach dem Login kopieren

SharedWorker-Geteilter Thread

Geteilter Thread
Freigegebene Threads können auf zwei Arten definiert werden: Erstens durch Erstellen einer URL, die auf eine JavaScript-Skriptressource verweist, und durch explizite Benennung dieser Ressource. Bei der Definition durch einen expliziten Namen wird die URL, die auf der ersten Seite verwendet wurde, die den freigegebenen Thread erstellt hat, als JavaScript-Skriptressourcen-URL für den freigegebenen Thread verwendet. Auf diese Weise können mehrere Anwendungen in derselben Domäne denselben gemeinsamen Thread verwenden, der einen gemeinsamen Dienst bereitstellt, wodurch die Notwendigkeit entfällt, dass alle Anwendungen Kontakt mit der URL aufrechterhalten, die einen gemeinsamen Dienst bereitstellt.

In jedem Fall wird der Umfang oder effektive Umfang eines gemeinsam genutzten Threads durch die Domäne definiert, in der er erstellt wird. Daher kommt es nicht zu Konflikten zwischen zwei verschiedenen Sites (d. h. Domänen), die denselben gemeinsamen Thread-Namen verwenden.

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

var worker = new SharedWorker(&#39;sharedworker.js&#39;, ’ mysharedworker ’ );
Nach dem Login kopieren
Nach dem Login kopieren

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

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

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

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

<!DOCTYPE html><html><head>
    <title>单个页面的SharedWorker</title></head><body>
    <h2>单个页面的SharedWorker</h2>
    <p id="show"></p>
    <script type="text/javascript">
        var worker = new SharedWorker(&#39;test.js&#39;);        var p = document.querySelector(&#39;#show&#39;);

        worker.port.onmessage = function(e){
            p.innerHTML = e.data;
        }    </script></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onconnect = function(e){
    var port = e.ports[0];
    port.postMessage(&#39;你好!&#39;);
}
Nach dem Login kopieren
Nach dem Login kopieren

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

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>在两个页面中共享后台线程</title><script type="text/javascript">var worker;function window_onload(){
    worker = new SharedWorker(&#39;test.js&#39;);    var p = document.getElementById(&#39;p1&#39;);
    worker.port.addEventListener(&#39;message&#39;, function(e) {
       p.innerHTML=e.data;
    }, false);
    worker.port.start();
    worker.port.postMessage(1);
}</script></head><body onload="window_onload()"><h1>在两个页面中共享后台线程</h1><p id="p1"></p></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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

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

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>在多个页面中通过共享后台线程来共享数据</title><script type="text/javascript">var worker;function window_onload(){
    worker = new SharedWorker(&#39;test2.js&#39;);    var p = document.getElementById(&#39;p1&#39;);
    worker.port.addEventListener(&#39;message&#39;, 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(&#39;get&#39;);
}</script></head><body onload="window_onload()"><h1>在多个页面中通过共享后台线程来共享数据</h1><input type="text" id="text"></input><button onclick="SendData()">提交数据</button><button onclick="getData()">获取数据</button></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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

HTML5-Multithreading-WebWorker

Web Worker

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");
};
Nach dem Login kopieren
Nach dem Login kopieren

或者,你也可以使用 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.
Nach dem Login kopieren
Nach dem Login kopieren

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

传递数据

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

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

<!DOCTYPE html><html><head>
    <title>webWorkers 实例演示</title></head><body>
    请输入要求和的数:<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(&#39;#num&#39;).value,10);            //2.将数据传递给子线程
            worker.postMessage(num);
        }        //3.从子线程接收处理结果并展示
        worker.onmessage = function(event){
            alert(&#39;总和为:&#39;+ event.data);
        }    </script></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onmessage = function(event){
    var result =0,
    num  = event.data;    for(var i = 1; i < num ;i ++){
        result += i;
    }    //向主线程返回消息
    postMessage(result);
}
Nach dem Login kopieren
Nach dem Login kopieren

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

HTML5-Multithreading-WebWorker

线程之间进行数据交互

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

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

<!DOCTYPE html><html><head>
    <title>线程之间进行数据交互</title></head><body>
    <h2>线程之间进行数据交互</h2>
    <table id="table" style="color: #FFF;background-color: #ccc;">

    </table></body>
    <script type="text/javascript">
        var nums = new Array(100),
        intStr = "";        //1.处理非字符串数据
        for(var i = 0; i<100; i++){
            nums[i] = parseInt(Math.random()*100);
            intStr += nums[i] + ";";
        }        //2.创建新进程
        var worker = new Worker("worker2.js");        //3.向子进程发送数据
        worker.postMessage(intStr);        //4.从子线程获取处理结果
        worker.onmessage = function(event){
            var row,
                col,
                tr,
                td,
                table = document.querySelector("#table");            var numArr = event.data.split(";");            for(var i = 0; i<numArr.length; i++){
                row = parseInt(i/10);
                col = i%10;                if (col == 0 ) {
                    tr = document.createElement("tr");
                    tr.id = "tr" + row;
                    table.appendChild(tr);
                }else{
                    tr = document.querySelector("#tr" + row);
                }
                td = document.createElement(&#39;td&#39;);
                tr.appendChild(td);
                td.innerHTML = numArr[i];
                td.width = "30";
            }
        }    </script></html>
Nach dem Login kopieren
Nach dem Login kopieren
onmessage = function(event){
    var strNum = event.data;    var numArr = strNum.split(";");    var returnNum = "";    for(var i =0; i<numArr.length; i++){        if (numArr[i]%3 ==0) {
            returnNum += numArr[i] + ";";
        }
    }
    postMessage(returnNum);

}
Nach dem Login kopieren
Nach dem Login kopieren

HTML5-Multithreading-WebWorker

线程间的嵌套

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

还是使用上述的实例,构造一个单层子线程嵌套的例子。把之前主页面生成随机数的工作放到后台线程,然后在后台线程中构造一个子线程,来挑选出可以被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;i<intArray.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>
Nach dem Login kopieren
Nach dem Login kopieren

script.js子线程代码

onmessage=function(event){
    var intArray=new Array(100);    //随机数组
    //生成100个随机数
    for(var i=0;i<100;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);
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

worker2.js代码

onmessage = function(event) {
    //还原整数数组
    var intArray= JSON.parse(event.data);    var returnStr;
    returnStr="";    for(var i=0;i<intArray.length;i++)
    {        //能否被3整除
        if(parseInt(intArray[i])%3==0)    
        {            if(returnStr!="")
                returnStr+=";";            //将能被3整除的数字拼接成字符串
            returnStr+=intArray[i];    
        }
    }    //返回拼接字符串
    postMessage(returnStr); 
    //关闭子线程          
    close();                         
}
Nach dem Login kopieren
Nach dem Login kopieren

HTML5-Multithreading-WebWorker

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

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

<!DOCTYPE html><html><head>
    <title>线程之间进行数据交互</title></head><body>
    <h2>线程之间进行数据交互</h2>
    <table id="table" style="color: #FFF;background-color: #ccc;">

    </table></body>
    <script type="text/javascript">

        var worker1 = new Worker("worker1.js");
        worker1.postMessage("");        //从子线程获取处理结果
        worker1.onmessage = function(event){
            var row,
                col,
                tr,
                td,
                table = document.querySelector("#table");            var numArr = event.data.split(";");            for(var i = 0; i<numArr.length; i++){
                row = parseInt(i/10);
                col = i%10;                if (col == 0 ) {
                    tr = document.createElement("tr");
                    tr.id = "tr" + row;
                    table.appendChild(tr);
                }else{
                    tr = document.querySelector("#tr" + row);
                }
                td = document.createElement(&#39;td&#39;);
                tr.appendChild(td);
                td.innerHTML = numArr[i];
                td.width = "30";
            }
        }    </script></html>
Nach dem Login kopieren
Nach dem Login kopieren

worker1.js代码

onmessage = function(event){
    var data = event.data;    var dataArr = new Array(100);    for(var i=0; i<100; 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);
    }

}
Nach dem Login kopieren
Nach dem Login kopieren

worker3.js代码

onmessage = function(event){
    var numArr = JSON.parse(event.data);    var returnNum = "";    for(var i =0; i<numArr.length; i++){        if (numArr[i]%3 ==0) {
            returnNum += numArr[i] + ";";
        }
    }
    postMessage(returnNum);

}
Nach dem Login kopieren
Nach dem Login kopieren

SharedWorker共享线程

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

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

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

var worker = new SharedWorker(&#39;sharedworker.js&#39;, ’ mysharedworker ’ );
Nach dem Login kopieren
Nach dem Login kopieren

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

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

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

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

<!DOCTYPE html><html><head>
    <title>单个页面的SharedWorker</title></head><body>
    <h2>单个页面的SharedWorker</h2>
    <p id="show"></p>
    <script type="text/javascript">
        var worker = new SharedWorker(&#39;test.js&#39;);        var p = document.querySelector(&#39;#show&#39;);

        worker.port.onmessage = function(e){
            p.innerHTML = e.data;
        }    </script></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onconnect = function(e){
    var port = e.ports[0];
    port.postMessage(&#39;你好!&#39;);
}
Nach dem Login kopieren
Nach dem Login kopieren

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

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>在两个页面中共享后台线程</title><script type="text/javascript">var worker;function window_onload(){
    worker = new SharedWorker(&#39;test.js&#39;);    var p = document.getElementById(&#39;p1&#39;);
    worker.port.addEventListener(&#39;message&#39;, function(e) {
       p.innerHTML=e.data;
    }, false);
    worker.port.start();
    worker.port.postMessage(1);
}</script></head><body onload="window_onload()"><h1>在两个页面中共享后台线程</h1><p id="p1"></p></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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

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

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>在多个页面中通过共享后台线程来共享数据</title><script type="text/javascript">var worker;function window_onload(){
    worker = new SharedWorker(&#39;test2.js&#39;);    var p = document.getElementById(&#39;p1&#39;);
    worker.port.addEventListener(&#39;message&#39;, 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(&#39;get&#39;);
}</script></head><body onload="window_onload()"><h1>在多个页面中通过共享后台线程来共享数据</h1><input type="text" id="text"></input><button onclick="SendData()">提交数据</button><button onclick="getData()">获取数据</button></body></html>
Nach dem Login kopieren
Nach dem Login kopieren
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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

HTML5-Multithreading-WebWorker

 以上就是html5 多线程处理webWorker的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage