概要
普段javascriptを書いているとよく使う非同期処理(Promise)だが、言語仕様上(
シングルスレッドのため)非同期処理は処理の順番を変えているだけで厳密には同期処理のようだった。
ざっくり図
同期処理
実行→結果→実行→結果...
非同期処理
実行→実行→結果→結果...
並列処理
実行→結果...
実行→結果...
よくよく調べているとWorker
オブジェクトを使用すれば並列処理ができるみたいなので試してみた
Document
ブラウサでの使用
※メインスレッド以外では、domの更新などができない
index.js
var worker = new Worker("./greeting-worker.js");
// データが送られてきたら発火
worker.onmessage = function (message) {
console.log(message)
// workerの停止
this.terminate();
};
// Worker作成時かWorker実行中でエラーとなった場合に発火
worker.onerror = function (err) {
console.error("onerror", err.message);
};
// データ送信
worker.postMessage("Hi");
greeting-worker.js
// worker.postMessageが呼ばれたら発火
self.onmessage = function (message) {
// 送られてきたデータ
console.log(message);
// workerにデータを送る
self.postMessage("I'm good.");
};
バックエンド(Node.js)での使用
index.js
var { Worker } = require("worker_threads");
var worker = new Worker("./greeting-worker.js");
// データが送られてきたら発火
worker.on("message", function (message) {
console.log(message);
// workerの停止
worker.terminate();
});
// Worker作成時かWorker実行中でエラーとなった場合に発火
worker.on("error", function (err) {
console.error("onerror", err.message);
// workerの停止
worker.terminate();
});
// workerが停止したら発火
worker.on("exit", function () {
console.log("Bye!!");
});
// データ送信
worker.postMessage("Hi, how are you?");
greeting-worker.js
// worker.postMessageが呼ばれたら発火
self.onmessage = function (message) {
// 送られてきたデータ
console.log(message);
// workerにデータを送る
self.postMessage("I'm good.");
};
// スレッドを増やしたい場合
var worker1 = new Worker("./worker1.js")
var worker2 = new Worker("./worker2.js")
var worker3 = new Worker("./worker3.js")
...
感想
あまり並列にすることもない処理でしたが、意外と簡単に扱うことができました。
使い所としては、処理が重い計算処理などやindexedDB(ブラウザ)があるそうです。
またワーカースレッドでデータをやりとりできるMessageChannel
というのもありました。(他ArrayBufferやFileHandleというものもあった)
まとめ
- javascriptは非同期処理の他に並列処理もできる
- ブラウザ/Node.jsともにAPIが用意されている.(使用感もほぼ同じ)
- メインスレッド以外では、domの更新などができない
- ワーカースレッドを増やしたい場合は複数Workerを呼び出す
- ワーカースレッド間でのデータのやりとりは
MessageChannel
を使用して行うことができる。