Creating a Future

The Future is not encoded as an ADT and thus we have to use a constructor that's provided by the companion object to construct it. Because the code we'll be providing will be executing in a separate thread, the Future has to have a way to obtain this Thread. This is done implicitly by having an ExecutionContext in scope, which we import in two steps. First, we'll import the whose scala.concurrent package in scope and the ExecutionContext from it:

scala> import scala.concurrent._
import scala.concurrent._
scala> import ExecutionContext.Implicits.global
import ExecutionContext.Implicits.global

The ExecutionContext is basically a factory for Threads. It can be configured as needed for specific use cases. For demonstration purposes, we're using global context, but in general, this is not recommended. Please refer to the ScalaDocs under https://www.scala-lang.org/api/current/scala/concurrent/ExecutionContext.html for further details.

Having this context in scope, we can construct a Future by providing a by-name parameter to its constructor:

val success = Future("Well")
val runningForever = Future {
while (true) Thread.sleep(1000)
}

The Future starts executing immediately after it is created, with respect to the time needed to obtain a thread from the executor.

Sometimes, we just want to wrap a value at hand into the Future for the code which expects some Future as a parameter. In this case, we don't need an execution context because we don't need to calculate anything. We can use one of the special constructors that help to create it successfully: failed and a Future from Try, respectively:

scala> val success = Future.successful("Well")
success: scala.concurrent.Future[String] = Future(Success(Well))
scala> val failure = Future.failed(new IllegalArgumentException)
failure: scala.concurrent.Future[Nothing] = Future(Failure(java.lang.IllegalArgumentException))
scala> val fromTry = Future.fromTry(Try(10 / 0))
fromTry: scala.concurrent.Future[Int] = Future(Failure(java.lang.ArithmeticException: / by zero))

There is also a predefined Future[Unit] that can be used as an indirect constructor by mapping over it:

scala> val runningLong = Future.unit.map { _ =>
| while (math.random() > 0.001) Thread.sleep(1000)
| }
runningLong: scala.concurrent.Future[Unit] = Future(<not completed>)

Now, since we have a value inside of the Future, let's take a look at the possible ways to get it out.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.81.33