direct use of Futures in Akka

2019-07-20 15:03发布

问题:

I am not able to create a Future as explained here. It says you can create a Future directly using the following code:

import akka.dispatch.Await
import akka.dispatch.Future
import akka.util.duration._

val future  = Future {
  "Hello" + "World"
}
val result = Await.result(future, 1 second)

Using the exact same code, I get an errormessage, saying: error: could not find implicit value for parameter executor: akka.dispatch.ExecutionContext. All I can find about the ExecutionContext is, that you can "do stuff" with it. In the documentation, the only line I found was:

implicit val ec = ExecutionContect.fromExecutionService(yourExecutionServiceGoesHere)

But this was not usefull to me. Has anyone any suggestion on that topic for me? How can I create a new Future without asking an Actor?

回答1:

If you have an ActorSystem then it will have an ExecutionContext which can be used here. It must be implicit, unless you pass it explicitly to the Future.apply method.

For the purposes of demonstration, if you just want to see how this works in the REPL:

implicit val system = ActorSystem("MySystem").dispatcher

(There is also an implicit conversion ActorSystem => ExecutionContext on the ExecutionContext object.)

To create modular code, without creating a context just before the point of use, consider making the context an abstract member of a trait:

trait MyFutures {
  implicit val context: ExecutionContext

  def helloFuture: Future[String] = Future { "hello" + "world" }
}


回答2:

Your code does not compile because you are writing illegal Scala code: the signature of Future.apply clearly states that. I assume you understand that you are calling the apply method of the companion object of the trait Future, which is the following:

object Future extends java.lang.Object with scala.ScalaObject {
  def apply[T](body : => T)(implicit executor : akka.dispatch.ExecutionContext) : akka.dispatch.Future[T] = { /* compiled code */ }
}

Since you do not have an implicit ExecutionContext available when calling Future.apply, you get a compilation error. It's the same as calling a method which receives two parameters if you provide just one.

The problem of how the ExecutionContext can be created is different, and you can find the answer in Akka Documentation:

In order to execute callbacks and operations, Futures need something called an ExecutionContext, which is very similar to a java.util.concurrent.Executor. if you have an ActorSystem in scope, it will use its default dispatcher as the ExecutionContext, or you can use the factory methods provided by the ExecutionContext companion object to wrap Executors and ExecutorServices, or even create your own.