从scala.concurrent.Future获取ActorRef [akka.actor.ActorRef]

时间:2013-10-16 19:20:05

标签: scala playframework akka

我正在尝试将ActorRef传递给调用客户端。这是一些代码:

object Sub {
  implicit val timeout = Timeout(5 seconds)
  lazy val default = {
    val subActor = Akka.system.actorOf(Props[Sub], "sub")
    subActor
  }

  def apply(pChannel: Concurrent.Channel[JsValue]):ActorRef = {
    (default ? Register(callback)).map {
      case ref:ActorRef => ref
    } 
  }
}

调用此方法的客户只需调用val sub:ActorRef = Sub(channel)

我遇到的问题是:

[error]  found   : scala.concurrent.Future[akka.actor.ActorRef]
[error]  required: akka.actor.ActorRef

如何修改上面的代码以获取调用代码的ActorRef以获得它需要的ref?

1 个答案:

答案 0 :(得分:2)

Future是稍后某个值的承诺。在这种情况下,Future[ActorRef]是一个值,表示现在或将来某个时刻的ActorRef。

你真的不想直接获取ActorRef,你可能想要将你的调用代码与返回的未来一起编写。

例如,如果您的代码执行:

val sub = Sub(channel)
doSomething(sub)

你想把它重写为:

Sub(channel).map { sub =>
  doSomething(sub)
}

因为这将创建一个新的未来,在doSomething(sub)值可用时自动调用sub。您还可以将示例重写为:

for(sub <- Sub(channel)) yield doSomething(sub)

如果您希望阻止调用代码并在可用时返回值(这违反了Akka,Play和反应式编程的设计原则),您可以始终使用Await,例如:

// Await.result() takes a Future[T] and returns a T
val sub = Await.result(Sub(channel), 10 seconds)

但是在库代码中执行此操作的设计很差,不建议这样做。你应该只在处理结束时等待期货,即使这样,框架通常会为你处理。