🌊

GopherJS で Worker を動かしてみた

2023/08/02に公開

GopherJS で Worker を動かしてみた

GopherJS を使用すると、 golang から JavaScript のコードに変換でき、ブラウザ上でも node.js 上でも動く JS のコードが Go言語から生成できる。今回、この GopherJS を使って Worker を動かすサンプルが執筆時点でまったく見当たらなかったので、実験してみた。

基本

素の JavaScript を使った Worker の使い方は以下のような感じ。

参考:https://qiita.com/suin/items/1537e0b4468705db45ce

<!DOCTYPE html>
<meta charset="UTF-8" />
<script>
  // ワーカーを起動するコード
  const myWorker = new Worker("worker.js");
  // ワーカーからのメッセージを受信する
  myWorker.addEventListener("message", (e) => {
    console.log("parent received message:", e.data);
  });
  // メッセージを送信する
  myWorker.postMessage("hey");
</script>

Worker 部分のコードは以下のような感じ。

// メッセージイベントを購読する
self.addEventListener("message", (e) => {
  // メッセージを受け取ったときに動かすコード
  console.log("worker received a message", e);
});
// 親にメッセージを送信する
self.postMessage("hello");

GopherJS

GopherJS でもやることは結局上の JavaScript のコードになるように Go言語で記述するだけ。

func main() {
	worker := js.Global.Get("Worker").New("/js/worker.js")
	worker.Call("addEventListener",
		"message", func(e *js.Object) {
			data := e.Get("data").String()
            println("parent received message: " + data)
        })
	worker.Call("postMessage", "hey")
}

Worker 部分の Go言語は以下の通り。

func main() {
	js.Global.Get("self").Call("addEventListener",
		"message", func(e *js.Object) {
			expr := e.Get("data").String()
            println("worker received a message: "+expr)
		})
	js.Global.Get("self").Call("postMessage", "hello")
}

この worker.go を gopherjs で JavaScript にコンパイルして worker.js と worker.js.map を生成し、上の index.go から呼び出せるように "/js/" 配下のパスへ配置するだけ。

結果

これだけで、ブラウザからアクセスしてみたところ、期待通りに Worker が動かせました。

Worker といえども、生成される JavaScript をイメージしながら Go言語で記述できれば、 GopherJS でも期待通りに動くことが確認できました。

Discussion