--- title: javascriptのWebWorkerを使ってみた tags: JavaScript jQuery WebWorker author: qiiChan slide: false --- ## 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 ```` ````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); ````