【问题标题】:Get ActorRef from scala.concurrent.Future[akka.actor.ActorRef]从 scala.concurrent.Future[akka.actor.ActorRef] 获取 ActorRef
【发布时间】:2013-10-26 12:52:48
【问题描述】:

我正在尝试将 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?

【问题讨论】:

    标签: scala playframework akka


    【解决方案1】:

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

    您并不想直接获取 ActorRef,您可能希望将调用代码与返回的未来组合起来。

    例如,如果您的代码这样做:

    val sub = Sub(channel)
    doSomething(sub)
    

    你想把它重写为:

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

    因为这将创建一个新的未来,当sub 值可用时自动调用doSomething(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)
    

    但在库代码中这样做是糟糕的设计,不推荐。您应该只在处理的最后等待期货,即使那样,框架通常也会为您处理。

    【讨论】:

    • 我看到 await 是 api.test 包的一部分。它在生产代码上也能正常工作吗?例如说实现长轮询
    • Await 不是 api.test 的一部分。见scala.concurrent.Await
    • 对!谢谢你的澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2018-05-11
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多