ホームページ  >  記事  >  ウェブフロントエンド  >  HTML5におけるJavaScriptマルチスレッドの詳細説明

HTML5におけるJavaScriptマルチスレッドの詳細説明

黄舟
黄舟オリジナル
2017-03-25 16:10:252083ブラウズ

Javascript のマルチスレッド - WebWorker HTML5 の Web Worker は 2 つの異なるスレッド タイプに分けることができます。1 つは専用スレッド Ddedated Worker で、もう 1 つは共有スレッド Shared Worker です。 2 種類のスレッドは目的が異なります。

専用の Web ワーカーは、それを作成したスクリプトに接続できますが、 とは通信できません。これは、このスレッドが一度に 1 つの要件のみを処理することを意味します。専用スレッドは IE を除くさまざまな主流ブラウザーに実装されており、安心して使用できます。実行するJavaScriptファイルのファイル名をスレッド通信
に渡すだけです。​​​​​​​​​​​​​​​ ​​​​​​​​​​​​​​​​​​​​​​​​ ​​​​​​​​​​​データを送信する相手には、送信者は postMessage メソッドを使用し、受信者は、渡されるデータという 1 つのパラメータのみを使用します。また、onmessage のパラメーターは 1 つだけです。イベントの場合は、event.data を使用します。
JSON

data を送信します。送信する受信データの取得データを

に送信するときエラーが発生すると、その onerror イベント コールバックが呼び出されます。そのため、エラーを処理する方法は、スレッド インスタンスの onerror イベントをフックすることです。このコールバック関数には、次の 3 つのフィールドがあります。エラーが発生したスクリプト ファイル; lineno - エラーが発生した行。

スレッドを破棄する

スレッド内で、close メソッドを使用してスレッド自体を破棄します。スレッド外のメインスレッドでは、スレッドインスタンスのterminateメソッドを使用してスレッドを破棄します。
HTML コード:

postMessage({'cmd': 'init', 'timestamp': Date.now()});

スクリプト ファイル fibonacci.js コード:
<script type="text/javascript">
  
onload
 = function(){
      var worker = 
new
 Worker(&#39;fibonacci.js&#39;);  
      worker.onmessage = function(event) {
        console.log("Result:" + event.data);
      };
      worker.onerror = function(error) {
        console.log("Error:" + error.message);
      };
      worker.postMessage(40);
  }  
  </script>
これらを同じディレクトリに配置し、ページ ファイルを実行してコンソールを確認すると、操作の結果が表示されます。

ここでもう 1 つのポイントがあります。メインスレッドでは、onmessage イベントを別の方法でフックできます。

//fibonacci.js
var fibonacci = function(n) {
    
return
 n < 2 ? n : arguments.c
all
ee(n - 1) + arguments.callee(n - 2);
};
onmessage = function(event) {
    var n = parseInt(event.data, 10);
    postMessage(fibonacci(n));
};
個人的には、非常に面倒なので、onmessage を直接使用する方が良いと思います。
他のスクリプト ファイルの使用

ワーカー スレッドは、グローバル メソッド importScripts を使用して、他のドメイン内スクリプト ファイルまたは

クラス ライブラリを読み込んで使用できます。たとえば、次は合法的な使用方法です:

worker.addEvent
List
ener(&#39;message&#39;, function(event) {
   console.log("Result:" + event.data);
}, false);
インポート後、これらのファイル内のメソッドを直接使用できます。インターネット上の小さな例を見てください:
importScripts();                        
importScripts(&#39;foo.js&#39;);                
importScripts(&#39;foo.js&#39;, &#39;bar.js&#39;);
インターネット上のネチズンの中には、ここで importScripts メソッドを使用してリソースのプリロードの問題を解決することを考えた人もいます (ブラウザーはリソースを解析して実行せずに事前にリソースをロードします)。理由もとても簡単です。

スレッドのネスト
作業スレッド内にサブスレッドを作成することもでき、さまざまな操作は同じです。

同期の問題
ワーカーにはロック機構がなく、マルチスレッドの同期問題はコードによってのみ解決できます (信号
変数

の定義など)。

共享型SharedWebWorker
  共享型web worker主要适用于多连接并发的问题。因为要处理多连接,所以它的API与专用型worker稍微有点区别。除了这一点,共享型web worker和专用型worker一样,不能访问DOM,并且对窗体属性的访问也受到限制。共享型web worker也不能跨越通信。
  页面脚本可以与共享型web worker通信,然而,与专用型web worker(使用了一个隐式的端口通信)稍微有点不同的是,通信是显式的通过使用一个端口(port)对象并附加上一个消息事件处理程序来进行的。

  在收到web worker脚本的首个消息之后,共享型web worker把一个事件处理程序附加到激活的端口上。一般情况下,处理程序会运行自己的postMessage()方法来把一个消息返回给调用代码,接着端口的start()方法生成一个有效的消息进程。
      看网上能找到的的唯一个例子:创建一个共享线程用于接收从不同连接发送过来的指令,然后实现自己的指令处理逻辑,指令处理完成后将结果返回到各个不同的连接用户。
HTML代码:

<script> 
  var worker = new SharedWorker(&#39;sharedworker.js&#39;); 
  var log = document.getElementByIdx_x_x_x_x(&#39;response_from_worker&#39;); 
  worker.port.addEventListener(&#39;message&#39;, function(e) { 
  //log the response data in web page 
  log.textContent =e.data; 
  }, false); 
  worker.port.start(); 
  worker.port.postMessage(&#39;ping from user web page..&#39;); 
  
  //following method will send user input to sharedworker 
  function postMessageToSharedWorker(input) 
  { 
  //define a json object to construct the request 
  var instructions={instruction:input.value}; 
  worker.port.postMessage(instructions); 
  } 
  </script>

 脚本文件代码:

 // 创建一个共享线程用于接收从不同连接发送过来的指令,指令处理完成后将结果返回到各个不同的连接用户。
 var connect_number = 0; 
 
 onconnect = function(e) { 
  connect_number =connect_number+ 1; 
  //get the first port here 
  var port = e.ports[0]; 
  port.postMessage(&#39;A new connection! The 
current
 connection number is &#39; 
  + connect_number); 
  port.onmessage = function(e) { 
   //get instructions from requester 
   var instruction=e.data.instruction; 
   var results=execute_instruction(instruction); 
    port.postMessage(&#39;Request: &#39;+instruction+&#39; Response &#39;+results 
      +&#39; from shared worker...&#39;); 
  }; 
 }; 
 function execute_instruction(instruction) 
 { 
 var result_value; 
 //implement your logic here 
 //execute the instruction... 
 return result_value;
 }

      在上面的共享线程例子中,在主页面即各个用户连接页面构造出一个共享线程对象,然后定义了一个方法 postMessageToSharedWorker 向共享线程发送来之用户的指令。同时,在共享线程的实现代码片段中定义 connect_number 用来记录连接到这个共享线程的总数。之后,用 onconnect 事件处理器接受来自不同用户的连接,解析它们传递过来的指令。最后,定义一个了方法 execute_instruction 用于执行用户的指令,指令执行完成后将结果返回给各个用户。

      这里我们并没有跟前面的例子一样使用到了工作线程的 onmessage 事件处理器,而是使用了另外一种方式 addEventListener。实际上,前面已经说过,这两种的实现原理基本一致,只是在这里有些稍微的差别,如果使用到了 addEventListener 来接受来自共享线程的消息,那么就要先使用 worker.port.start() 方法来启动这个端口。之后就可以像工作线程的使用方式一样正常的接收和发送消息

线程中能做的事
1.能使用setTimeout(), clearTimeout(), setInterval(),clearInterval()等函数。
2.能使用navigator对象。
3.能使用XMLHttpRequest来发送请求。
4.可以在线程中使用Web Storage。

5.线程中可以用self获取本线程的作用域。

线程中不能做的事
1.线程中是不能使用除navigator外的DOM/BOM对象,例如window,document(想要操作的话只能发送消息给worker创建者,通过回调函数操作)。
2.线程中不能使用主线程中的变量和函数。
3.线程中不能使用有"挂起"效果的操作命令,例如alert等。
4.线程中不能跨域加载JS。

线程也是需要消耗资源的,而且使用线程也会带来一定的复杂性,所以如果没有充足的理由来使用额外的线程的话,那么就不要用它。

以上がHTML5におけるJavaScriptマルチスレッドの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。