WebWorkerをインラインで簡潔に書く【インラインの鬼】
WebWorkerをインラインで簡潔に書く【インラインの鬼】:
いちいち別ファイルを用意するのは癪なので、WebWorkerをインラインでサクッと実装する方法を調べてみました。
node.jsは
Workerで処理させる内容を、メソッドとして書いて行きます。
インラインだと忘れてしまいがちですが、このメソッドはあくまでWorkerとして実行されるので、DOM操作などは出来ません。
そして
ここがミソ。
引数として受け取ったWorkerソースメソッドに文字列
FireFoxだと
文字列化されたWorkerソースはBlob化されます。
ここまで来ると、1つのソースファイルを読み込んだのと同じですね。
そして
(神IEだとローカルで実行出来ません、またお前か)
後は
StackBlitz Online Demo
StackBlitz始めました。
かなり便利です。
他にも、
これが一番、直感的に理解しやすいと思いました。
いちいち別ファイルを用意するのは癪なので、WebWorkerをインラインでサクッと実装する方法を調べてみました。
node.jsは
cluster
モジュールがあるので楽チンなのですが...
Workerの中身を書く
Workerで処理させる内容を、メソッドとして書いて行きます。インラインだと忘れてしまいがちですが、このメソッドはあくまでWorkerとして実行されるので、DOM操作などは出来ません。
そして
this
はDedicatedWorkerGlobalScope
を指します。Worker
function source(){ const self = this; self.addEventListener("message", (event)=>{ self.postMessage({ rx: `Worker Received: ${event.data}`, tx: "Message from Worker" }); self.close(); }); }
Workerを生成する
ここがミソ。引数として受け取ったWorkerソースメソッドに文字列
()();
を結合して、即時関数化と文字列化を同時に行っています。FireFoxだと
"use strict";
が自動付与されてしまう為、削除しています。文字列化されたWorkerソースはBlob化されます。
ここまで来ると、1つのソースファイルを読み込んだのと同じですね。
そして
new Worker()
コンストラクタで、生成したBlobをBlobURLとして指定します。(神IEだとローカルで実行出来ません、またお前か)
Main
function createWorker(func){ const blob = new Blob([`(${func})();`.replace(/"use strict";/, "")]); return new Worker(URL.createObjectURL(blob)); }
実行
後はcreateWorker()
でWorkerソースメソッドを指定して、インスタンスを生成するだけです。Main
const worker = createWorker(source); worker.addEventListener("message", (event)=>{ console.log(event.data.rx); console.log(`Main Received: ${event.data.tx}`); }); worker.postMessage("Message from Main");
ズバリ
index.js
function source(){ const self = this; self.addEventListener("message", (event)=>{ self.postMessage({ rx: `Worker Received: ${event.data}`, tx: "Message from Worker" }); self.close(); }); } function createWorker(func){ const blob = new Blob([`(${func})();`.replace(/"use strict";/, "")]); return new Worker(URL.createObjectURL(blob)); } const worker = createWorker(source); worker.addEventListener("message", (event)=>{ console.log(event.data.rx); console.log(`Main Received: ${event.data.tx}`); }); worker.postMessage("Message from Main");
オンラインデモ
StackBlitz Online DemoStackBlitz始めました。
かなり便利です。
結論
他にも、eval
を使うとか、自分自身を丸ごと読み込むとか、色々と出てきましたが...これが一番、直感的に理解しやすいと思いました。
コメント
コメントを投稿