Scala.jsで並列処理をする
Scala.jsで並列処理したい。したくない?
オススメはWeb Workerです。Future使っても、jsの制約で結局シングルスレッド実行されるようなので。
javascriptのWeb Workerを使う
以下のGistを参考にしてください。
ポイント1
@JSExport("WorkerMain") object WorkerMain { @JSExport def main(): Unit = { ...
と@JSExport
をつけて、worker.js
から
WorkerMain().main();
のように呼び出せるようにしています。
ポイント2
グローバルオブジェクトのWorkerにアクセスできるよう、
@js.native
でオブジェクトを定義しています。
@js.native object WorkerGlobal extends js.GlobalScope { def addEventListener(`type`: String, f: js.Function): Unit = js.native def postMessage(data: js.Any): Unit = js.native }
ScalaのFuture, Promiseを使う
Scalaコードは普通に書きます。以下のようにScala.js用のExecutionContext
をimport
します。
import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue
可能であればjsのPromise
を使い、
そうでなければ、setTimeout(..., 0)
と同様、jsの実行時タスクキューに積まれます。
jsエンジン?の実装によるんでしょうが、Chromeでは、
Future
処理が終わるまで親処理が止まってしまって使い物になりませんでした。
※ scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow
というのもありますが、現在はdeprecatedになっています。
これをimport
すると、Future
は直ちに実行されます。並列実行じゃないね。