2025-11-22 (土)

天気がいい。
夜、望遠鏡と双眼鏡を覗いてたのだけど、人工衛星が横切る頻度が子供の頃と比べて明らかに増えてる。
この日記はフィクションです.登場する人名・団体名・地名・職業などはぜんぶ架空のものです. なので実際のものとは何も関係がありません. それから,写真のように見える画像はCGもしくは念写によるものです.
明日から一週間休み。
gojaでgoroutineで実装された非同期処理をjsから呼び出したり、逆にjs側で作ったPromiseをgoで待ったりする実装をしてたけど、基本的にgoroutine-safeでないので慣れないととても書きにくい。。。せめてPromiseに他のgoroutineからアクセスしたい。処理の奥深くからイベントループにタスクを追加しないといけなくなるので、イベントループを管理するインスタンスをjs側のグローバルな値としてセットしておくのが無難そう。
Goで実装されたJavaScriptエンジンのgojaがいつのまにか比較的モダンなJSを実行できるようになっていた。
https://github.com/dop251/goja
README の最初に ECMAScript 5.1(+) とか書かれているけど、実施はES2017あたりまでサポートされていそう?(モジュールは無い)
async/awaitとかも実装されている。goja自体にevent loopが無いのでそのままだと非同期処理を実行できないけど、 https://github.com/dop251/goja_nodejs にeventloopパッケージがある。
ただ、nodejs互換の環境を作る用途で実装されてるようなので、NewEventLoop()内で色々追加されてしまったり、RunしないとRuntimeオブジェクトを取れないのと、Go側で作ったPromiseとかは自分で管理しないといけないのが不便。最終的には自前で実装したほうが無難かもしれない。
package main import ( "github.com/dop251/goja" "github.com/dop251/goja_nodejs/eventloop" ) const SCRIPT = ` class AsyncTest { async run() { for (let i = 0; i < 10; i++) { await new Promise((r) => setTimeout(r, 200)); console.log(i); } } } (new AsyncTest()).run(); ` func main() { loop := eventloop.NewEventLoop() loop.Run(func(vm *goja.Runtime) { _, err := vm.RunString(SCRIPT) if err != nil { panic(err) } }) }
今までquickjsのbindingを使うのが無難だと思ってたけど、CGOが必要になってしまうのと、パフォーマンスが微妙だった。gojaはGoの上で動作しているのでシンプルな実装のわりに実行速度が速そう。