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?
A Future is a placeholder object for a value that may not yet exist. Generally, the value of the Future is supplied concurrently and can subsequently be used. Composing concurrent tasks in this way tends to result in faster, asynchronous, non-blocking parallel code.
Promise. The Promise is a writable, single-assignment container that completes a Future. The Promise is similar to the Future. However, the Future is about the read-side of an asynchronous operation, while the Promise is about the write-side.
An ExecutionContext can execute program logic asynchronously, typically but not necessarily on a thread pool. A general purpose ExecutionContext must be asynchronous in executing any Runnable that is passed into its execute -method.
NOTE: With Future. onComplete() we are no longer blocking for the result from the Future but instead we will receive a callback for either a Success or a Failure.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With