html5 マルチスレッド WebWorker

黄舟
リリース: 2017-02-16 14:21:47
オリジナル
1668 人が閲覧しました

Web Worker

Web Worker は、Web コンテンツがバックグラウンドでスクリプトを実行できるようにする簡単な方法を提供します。ワーカーが作成されると、その作成者が指定したイベント リスナー関数にメッセージを渡すことができるため、ワーカーによって生成されたすべてのタスクがこれらのメッセージを受信します

ワーカー スレッドは、UI を妨げることなくタスクを実行できます。さらに、XMLHttpRequest (ただし、responseXML およびチャネル属性値は常に null ですが) を使用して I/O 操作を実行することもできます。

ワーカーの生成

新しいワーカーの作成は非常に簡単です。ワーカー スレッド内で実行するスクリプトの URI を指定して、Worker() コンストラクターを呼び出すだけです。ワーカーから通知を受け取りたい場合は、ワーカーの onmessage 属性を特定のイベント ハンドラーに設定できます。

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

myWorker.onmessage = function (oEvent) {
  console.log("Called back by the worker!\n");
};
ログイン後にコピー
ログイン後にコピー

または、addEventListener() を使用することもできます。 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 不会共享同一个实例,最终的结果就是在每次通信结束时生成了数据的一个副本。大部分浏览器使用结构化拷贝来实现该特性。

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

<!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>
ログイン後にコピー
ログイン後にコピー
onmessage = function(event){
    var result =0,
    num  = event.data;    for(var i = 1; i < num ;i ++){
        result += i;
    }    //向主线程返回消息
    postMessage(result);
}
ログイン後にコピー
ログイン後にコピー

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

html5 マルチスレッド WebWorker

线程之间进行数据交互

线程间的数据交互是通过发送和接收消息来相互传递信息的,主线程首先创建Worker,通过Worker对象的postMessage方法,将数据传递给后台线程,而主程序通过onmessage 事件,或者自定义addEventListener

<!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>
ログイン後にコピー
ログイン後にコピー
例の最初の行は、新しいワーカー スレッドを作成します。 3 行目は、ワーカー上のメッセージ イベントのリスナー関数を設定します。このイベント ハンドラーは、ワーカーが独自の postMessage() 関数を呼び出すときに呼び出されます。最後に、7 行目でワーカー スレッドを開始します。

データの送信

html5 マルチスレッド WebWorker

メインページとワーカーの間で転送されるデータは、

共有

ではなく

コピー

を通じて行われます。ワーカーに渡されるオブジェクトは

シリアル化

する必要があり、その後、反対側で

逆シリアル化する必要があります。ページとワーカーは同じインスタンスを共有しないため、最終的には各通信の終了時にデータのコピーが生成されます。ほとんどのブラウザは、構造化コピーを使用してこの機能を実装します。

例:合計を計算するサブスレッドを作成する

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);

}
ログイン後にコピー
ログイン後にコピー
<!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>
ログイン後にコピー
ログイン後にコピー

時間のかかる処理をバックグラウンドスレッドに渡して処理し、処理後に結果をメインページに返すことができます。

html5 マルチスレッド WebWorkerhtml5 マルチスレッド WebWorker

スレッドスレッド間のデータ対話

スレッド間のデータ対話は、メッセージの送受信によって相互に情報を転送します。

メイン スレッドは最初に Worker を作成し、Worker オブジェクトの postMessage メソッドを通じてデータをバックグラウンド スレッドに渡します。 onmessage イベントを渡すか、バックグラウンドをリッスンしてバックグラウンド スレッド処理の結果を返すように addEventListener イベントをカスタマイズします。同様に、バックグラウンド スレッドは、メイン ページから onmessage イベントを通じて渡されたデータを受け取り、処理結果を postMessage を通じてメイン ページに返します。

例: ページ シーケンスは 100 個のデータをランダムに生成し、そのデータをフィルタリングのためにバックグラウンド スレッドに渡します。3 で均等に分割できるデータはメイン ページに返され、動的テーブルの形式で表示されます。

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);
    }
}
ログイン後にコピー
ログイン後にコピー
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();                         
}
ログイン後にコピー
ログイン後にコピー

スレッド間のネスト

サブスレッドはスレッド内にネストできるため、より大きなバックグラウンド スレッドを複数のサブスレッドに分割でき、各サブスレッド グリッドは比較的独立した作業を完了できます。

上記の例を引き続き使用して、単一層のサブスレッドのネストの例を構築します。メインページで乱数を生成する以前の作業をバックグラウンド スレッドに組み込み、次にバックグラウンド スレッド内に 3 で割ることができるデータを選択するサブスレッドを構築します。渡されるデータは JSON データ形式です。

<!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>
ログイン後にコピー
ログイン後にコピー

script.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);
    }

}
ログイン後にコピー
ログイン後にコピー
🎜🎜worker2.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);

}
ログイン後にコピー
ログイン後にコピー
🎜🎜🎜🎜 サブスレッドにメッセージを配信する場合は、worker.postMessage を使用します。メイン ページにデータを送信する場合は、worker.postMessage を使用します。 postMessage を直接🎜🎜 複数のサブスレッド間のデータ対話🎜
var worker = new SharedWorker(&#39;sharedworker.js&#39;, ’ mysharedworker ’ );
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
🎜🎜worker1.js コード🎜🎜
 // 从端口接收数据 , 包括文本数据以及结构化数据
 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;]});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
🎜🎜worker3.js コード🎜🎜
<!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>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
🎜SharedWorker 共有スレッド🎜🎜🎜共有スレッド🎜🎜 共有スレッドは 2 つの方法で定義できます。1 つは、JavaScript スクリプト リソースを指す URL を作成する方法、または明示的な名前を使用する方法です。明示的な名前で定義すると、共有スレッドを作成した最初のページで使用された URL が、共有スレッドの JavaScript スクリプト リソース URL として使用されます。このようにして、同じドメイン内の複数のアプリケーションが共通のサービスを提供する同じ共有スレッドを使用できるようになり、すべてのアプリケーションが共通のサービスを提供する URL との接続を維持する必要がなくなります。 🎜🎜どのような状況であっても、共有スレッドのスコープまたは有効範囲は、それが作成されたドメインによって定義されます。したがって、同じ共有スレッド名を使用する 2 つの異なるサイト (つまり、ドメイン) が競合することはありません。 🎜

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

var worker = new SharedWorker(&#39;sharedworker.js&#39;, ’ mysharedworker ’ );
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

与共享线程通信
共享线程的通信也是跟专用线程一样,是通过使用隐式的 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;]});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

上面示例代码中,第一个我们使用 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>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
onconnect = function(e){
    var port = e.ports[0];
    port.postMessage(&#39;你好!&#39;);
}
ログイン後にコピー
ログイン後にコピー

实例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>
ログイン後にコピー
ログイン後にコピー
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

只要发送不同的数据就可以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>
ログイン後にコピー
ログイン後にコピー
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

html5 マルチスレッド 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");
};
ログイン後にコピー
ログイン後にコピー

或者,你也可以使用 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 不会共享同一个实例,最终的结果就是在每次通信结束时生成了数据的一个副本。大部分浏览器使用结构化拷贝来实现该特性。

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

<!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>
ログイン後にコピー
ログイン後にコピー
onmessage = function(event){
    var result =0,
    num  = event.data;    for(var i = 1; i < num ;i ++){
        result += i;
    }    //向主线程返回消息
    postMessage(result);
}
ログイン後にコピー
ログイン後にコピー

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

html5 マルチスレッド 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>
ログイン後にコピー
ログイン後にコピー
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);

}
ログイン後にコピー
ログイン後にコピー

html5 マルチスレッド 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>
ログイン後にコピー
ログイン後にコピー

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);
    }
}
ログイン後にコピー
ログイン後にコピー

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();                         
}
ログイン後にコピー
ログイン後にコピー

html5 マルチスレッド 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>
ログイン後にコピー
ログイン後にコピー

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);
    }

}
ログイン後にコピー
ログイン後にコピー

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);

}
ログイン後にコピー
ログイン後にコピー

SharedWorker共享线程

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

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

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

var worker = new SharedWorker(&#39;sharedworker.js&#39;, ’ mysharedworker ’ );
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

与共享线程通信
共享线程的通信也是跟专用线程一样,是通过使用隐式的 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;]});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

上面示例代码中,第一个我们使用 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>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
onconnect = function(e){
    var port = e.ports[0];
    port.postMessage(&#39;你好!&#39;);
}
ログイン後にコピー
ログイン後にコピー

实例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>
ログイン後にコピー
ログイン後にコピー
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

只要发送不同的数据就可以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>
ログイン後にコピー
ログイン後にコピー
onconnect = function(e) {
   var port = e.ports[0];
   port.onmessage = function(e) {
     port.postMessage(e.data*e.data);
   }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

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

html5 マルチスレッド WebWorker

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


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート