Futures in Scala.js

future, javascript, promise, scala, scala.js

Solution

Since Scala.js 0.6.0, the standard `global` `ExecutionContext` of Scala is available in Scala.js. You can import it with

import scala.concurrent.ExecutionContext.Implicits.global

// now you get to play with Futures

In Scala.js, it is an alias to `scala.scalajs.concurrent.JSExecutionContext.Implicits.queue`. This execution context enqueues jobs in the standard JavaScript event loop.

Note that tasks are executed asynchronously, but not in parallel, since JavaScript has no notion of parallelism per se. If parallelism is required, Web Workers need to be used, but those do not provide the shared-memory model required by `Future`s as such.

Old answer applying to Scala.js < 0.6.0

There are 2 existing and working `ExecutionContext`s in `scala.scalajs.concurrent.JSExecutionContext`, with implicit versions in the inner object `Implicits`. Simply import the one that makes sense for you (probably `queue`, the other one not being actually asynchronous).

import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue

// now you get to play with Futures

Problem

I tried to use Promises and Futures in Scala.js. Promise works, as soon as it comes to Futures I get warnings and errors. Try: ``` val p1 = Promise[Int] val f1: Future[Int] = p1.future val p2 = Promise[Int] val f2: Future[Int] = p2.future val res1 = for { v1 <- f1 v2 <- f2 } yield v1 + v2 val res2 = f1.flatMap(x => f2.map(y => x + y)) res1 onSuccess { case x: Int => g.console.log(x); } res2 onSuccess { case x: Int => g.console.log(x); } // callback in dom, using ScalaTags // div(`class` := "btn btn-default", `type` := "button", onclick := click(1, p1)) def click(i: Int, p: Promise[Int])(x: dom.MouseEvent): Unit = { g.console.log(i); try { p success i } catch { case x: Throwable => println("again") } } f1 onSuccess { case x: Int => 1 } ``` And I get in sbt fastOptJs: ``` [warn] Referring to non-existent class jl_Thread$UncaughtExceptionHandler [warn] called from s_concurrent_impl_ExecutionContextImpl.init___ju_concurrent_Executor__F1 [warn] called from s_concurrent_impl_ExecutionContextImpl$.fromExecutor__ju_concurrent_Executor__F1__s_concurrent_impl_ExecutionContextImpl [warn] called from s_concurrent_ExecutionContext$Implicits$.global$lzycompute__p1__s_concurrent_ExecutionContextExecutor [warn] called from s_concurrent_ExecutionContext$Implicits$.global__s_concurrent_ExecutionContextExecutor [warn] called from Lexample_H2$class.Lexample_H2$class__$init$__Lexample_H2__V [warn] ``` And I get in the browser: ``` uncaught exception: java.lang.RuntimeException: System.getProperty() not implemented ``` What is missing/unimplemented? How can I implement it? Is there a workaround? How can I implement an ExecutionContext that is makes sense to handle Events withing the browser?

Original source