概要
普段javascriptを書いているとよく使う非同期処理(Promise)だが、言語仕様上(
シングルスレッドのため)非同期処理は処理の順番を変えているだけで厳密には同期処理のようだった。
ざっくり図
同期処理
実行→結果→実行→結果...
非同期処理
実行→実行→結果→結果...
並列処理
実行→結果...
実行→結果...
よくよく調べているとWorker
オブジェクトを使用すれば並列処理ができるみたいなので試してみた
Document
- Docs Worker
ブラウサでの使用
※メインスレッド以外では、domの更新などができない
index.js
varworker=newWorker("./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");varworker=newWorker("./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.");};
// スレッドを増やしたい場合varworker1=newWorker("./worker1.js")varworker2=newWorker("./worker2.js")varworker3=newWorker("./worker3.js")...
感想
あまり並列にすることもない処理でしたが、意外と簡単に扱うことができました。
使い所としては、処理が重い計算処理などやindexedDB(ブラウザ)があるそうです。
またワーカースレッドでデータをやりとりできるMessageChannel
というのもありました。(他ArrayBufferやFileHandleというものもあった)
まとめ
- javascriptは非同期処理の他に並列処理もできる
- ブラウザ/Node.jsともにAPIが用意されている.(使用感もほぼ同じ)
- メインスレッド以外では、domの更新などができない
- ワーカースレッドを増やしたい場合は複数Workerを呼び出す
- ワーカースレッド間でのデータのやりとりは
MessageChannel
を使用して行うことができる。