あっくんブログ Written by Akihiro Tsuji

JavaScriptのWeb Worker

JavaScript プログラミング

こんにちはあっくんです。ようやく風邪が治りそうです。いつまで引いているのかという感じです。もはや、10日以上です。ほんとに体弱いかもです。最近夜が眠れなくて、心身共に回復しないという状態です。改めて、健康あっての人生と日々痛感しながら、今日こそは早く寝て、途中起きないようにしたいです。身体弱ってますが、ランニングとトレーニングをしました。

今回はJavaScriptのWeb worker についてやっていきましょう!

Web Workerはバックグラウンドのスレッドで処理する方法が用意されています。JavaScriptは基本的にシングルスレッドです。
new Worker()でWorkerオブジェクトを作成します。そして、Workerメッセージを送ったり、Workerからメッセージを受け取ったりすることで、別のスレッドとやり取りをします。

構文

worker = new Worker(外部JavaScriptのURLのURLRL) worker.postMessage(送信するデータ worker.onmessage = function(event) { event.dataが受信するデータ }
Code language: JavaScript (javascript)

Workerの処理は別スレッドで実行します。
WorkerのスレッドとJavaScriptのメインスレッドは文字列やオブジェクトといったデータを送りあうことができます。しかし、WorkerはJavaScriptのメインスレッドとメモリーを共有できません。そのため、データをシリアライズします。シリアライズは直列化、つまり、文字列や、バイト列のように、階層構造をもたないデータ構造に変換します。そのため、データの複製を作って送ることになります。Workerに送ったデータを書き換えても、元のデータは変化しません。

Worker側では、onmessageを利用してデータを受け取ります。データを戻すときにはpostMessage()を使います。

構文

onmessage = function(event) { event.dataが受信するデータ postMessage(送信するデータ }
Code language: JavaScript (javascript)

WokerはJavaScriptのメインスレッドとは別に、バックグラウンドのスレッドで処理を行なうので、時間のかかる思い計算を行なうのに適しています。画像処理や、解析処理など、数秒かかってしまう処理は、Wokerを使ってユーザーの操作を妨げないようにしましょう。

Workerの処理はサーバー上にファイルがある時に動きます。

例、Workerとして、動作する処理。

Image from Gyazo

「web-worker.js」

onmessage = function(event) { // データをJSON化して、コンソールに出力 console.log("@worker", JSON.stringify(event.data)); // 返信するデータを作成 const data = { msg: "返信!", arr: [4, 5, 6] }; // 呼び出し元にデータを送信 postMessage(data); };
Code language: JavaScript (javascript)

「web-worker.html」

<html> <script> console.log("--- 開始 ---"); // Workerを作成 const worker = new Worker("web-worker.js"); // 送信するデータを作成 const data = { msg: "送信", arr: [1, 2, 3], }; // Workerに値を送信 worker.postMessage(data); // Workerから送信された値をコンソールに出力 worker.onmessage = function(event) { // データをJSON化してコンソールに出力 console.log("@html", JSON.stringify(event.data)); }; console.log("--- 終了 ---"); </script> </html>
Code language: HTML, XML (xml)

例、Workerを使った処理。Workerの処理はサーバー上にファイルがある時に動きます。

Image from Gyazo

「web-worker-wait.js」

// 送信されたデータを取得 onmessage = function(event) { // データをコンソールに出力 console.log("@worker", event.data); // 時間のかかる処理 for (let i = 0; i < 5000; i++) { const str = [... "@".repeat(5000) ].join(); // 1000ごとにコンソールに経過を出力 if (i % 1000 === 0) { console.log("@worker", i); } } // 呼び出し元にデータを送信 postMessage("返信!"); };
Code language: JavaScript (javascript)

「web-worker-wait.html」

<html> <script> // Workerを作成 const worker = new Worker("web-worker-wait.js"); // Workerに値を送信 worker.postMessage("送信!"); // Workerから送信された値をコンソールに出力 worker.onmessage = function(event) { // データをコンソールに出力 console.log("@html", event.data); // 待機処理をクリア clearInterval(intervalID); }; // 待機処理 let cnt = 0; const intervalID = setInterval(() => { console.log("@html", "wait...", cnt++); }, 100); </script> </html>
Code language: HTML, XML (xml)

Shared Worker

Shared Workerは複数開いているWebブラウザのタブやウィンドウで、情報を共有できるWorkerです。単一の共通Workerを走らせて、まとめて処理を行います。Shared Workerはport経由でメッセージの送受信をします。

html側の構文

worker = new ShareWorker(外部JavaScriptのURLのURLRL) worker.port.postMessage(送信するデータ worker.port.onmessage = function(event) { event.dataが受信するデータ }
Code language: JavaScript (javascript)

Worker側の構文

onconnect = function(event) { port = event.port[0]; port.onmessage = function(event) { event.dataが受信するデータ port.postMessage(送信するデータ } }
Code language: JavaScript (javascript)

例、Shared Workerを使った処理。複数のタブで同じURLを開き、コンソールをひらいて、cntの情報が共有されていることを確認します。

Image from Gyazo

「shared-worker.js」

// カウンター用変数 let cnt = 0; // 送信されたデータを取得 onconnect = function(event) { const port = event.port[0]; port.onmessage = function(event) { // データをコンソールに出力 console.log("@worker", event.data); // 呼び出し元にデータを送信 port.postMessage(`返信!${++cnt}`); }; };
Code language: JavaScript (javascript)

「shared-worker.html」

<html> <script> // Workerを作成 const worker = new SharedWorker("shared-worker.js"); // Workerに値を送信 worker.port.postMessage("送信!"); // Workerから送信された値をconsoleに出力 worker.port.onmessage = function(event) { // データをコンソールに出力 console.log("@html", event.data); }; </script> </html>
Code language: HTML, XML (xml)

読んでいただいて、ありがとうございました!JavaScript完全入門、手元に置いておきたい一冊です。