Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
58
Help us understand the problem. What is going on with this article?
@qiiChan

javascriptのWebWorkerを使ってみた

More than 3 years have passed since last update.

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);
58
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
qiiChan
フリーランスエンジニアです。 お仕事のご相談など、お気軽にご相談くださいm(_ _)m キーワード  WEB開発、フルスクラッチ、azure、aws、docker、機械学習、データ分析、環境シミュレーション、fortran

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
58
Help us understand the problem. What is going on with this article?