LoginSignup
77
77

More than 5 years have passed since last update.

javascriptのWebWorkerを使ってみた

Last updated at Posted at 2017-11-11

WebWorkerとは?

初心者です。

WebWorkerとはjavascriptでマルチスレッドを行うための仕組みです。
マルチスレッドとは、複数の処理を同時に行うことです。

例えば、描画処理などで
 ・データ取得処理
 ・取得したデータの描画処理
を同時に行うと描画が滞りなく行われます。

処理を同時に行わない場合は、

 データ取得 → 描画 → データ取得 → 描画 → ・・・

となり、データ取得の度に描画が止まります。これを

 処理A :データ取得 → データ取得 → ・・・
 処理B :描画    → 描画    → ・・・

の様に処理A、Bを同時に行ってスムーズに描画するという機能です。
(あくまで一例。処理が軽い場合は普通に記述して問題ない)

非同期処理は?

javascriptは非同期処理でpromiseなどありますが、
あれは処理の順番を変えているだけで同時に処理を行うものではありません(でした)。

 非同期処理 = 並行して処理を行ってくれる

と考えがちですが、javascriptは(原則)違います。

概要とか特徴

概要
 ・メインスレッド(main.js) ←メイン処理
 ・サブスレッド(doWork.js) ←main.jsから呼び出して並行して処理

特徴
 ・処理ごとにファイルを分ける。
 ・データのやり取りはJSON等で行う。他にもある。
 ・サブスレッド(doWork.js)から、DOM操作(タグ編集とか)は出来ない。
   window.document.form.****とかはNG
 ・jQueryもダメ($ajaxとか)。レスポンスには適用できる。
 ・通信は、XMLHttpRequestやfetchなどで出来る。

基本的な使い方

 同時進行で行う処理を、doWorker.jsに記述する。
 main.jsでdoWorker.jsを呼び出す。

index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
  <script src="js/main.js"></script>
</head>
<body>
    <input type="text"   id="idParamPost"    value="送信メッセージ">
    <input type="text"   id="idParamReceive" value="">
    <input type="button" id="idBtnDoPost"    value="送信">
</body>
</html>
main.js
//送信
$(document).on('click', '#idBtnDoPost', function(){

  //workerオブジェクト
  var worker = new Worker('js/doWork.js');

  //処理結果、受信イベント
  worker.addEventListener('message', function(e) {
    $("#idParamReceive").val(e.data);
  }, false);

  //処理命令
  worker.postMessage($("#idParamPost").val());
});
doWork.js
//worker
self.addEventListener('message', function(e) {

  //何か同時進行で行う処理

  //処理結果を送信
  self.postMessage(e.data);
}, false);

注意
 main.jsのコードの書き順は決まっている様なので、この通りに書く。

マルチスレッドな使い方

 上記では、いまいちWebWorkerの有難味が分からない。
 これが便利だと思えるのは、(繰り返しになるが)下記の様な描画処理である。
 同時に行わない場合は、データ取得の度に描画が止まる。
 下記の例では受け取る配列(aryJSON)は1つであるが、受信するバッファを複数にしたり、
 バッファの要素数を調節したりと、ケースによる調整は必要である。

main.js

//処理開始
$(document).on('click', '#idBtnDoPost', function(){

  //非同期で受信するデータ
  var aryJSON = [];

  //workerオブジェクト
  var worker = new Worker('js/doWork.js');

  //受信イベント
  worker.addEventListener('message', function(e) {
    aryJSON = e.data;  //処理ループ内で使用するデータ
  }, false);

  //処理ループ
  while(true){

    //非同期でデータ取得
    worker.postMessage($("#idParamPost").val());

    //取得したデータ表示
    viewJSON(aryJSON);
  }

});

豆知識

 jsonデータを送受信する場合は、下記の様にパースする。

doWork.js
//worker
self.addEventListener('message', function(e) {
  //メッセージ送信
  self.postMessage(JSON.parse(e.data));  //JSONにパース
}, false);
77
77
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
77
77