【问题标题】:How to get object inside a Future in Scala如何在Scala中的Future中获取对象
【发布时间】:2017-12-22 02:04:35
【问题描述】:

我使用 Akka myActor1 向另一个 myActor2 询问未来的响应,如下所示:

val future = myActor2 ? request
val result = Await.result(future, timeout.duration).asInstanceOf[Person]

假设结果是这样的案例类:

case class Person(name: String, age: Int)

我不想阻止进程,所以我选择不使用 Await.result。 因此我有以下代码:

val future = (myActor2 ? request).mapTo[Person]

现在 future 是 Future[Person] 而不是 Future[Any]。 那么我怎样才能提取未来包含的人并处理异常? 我用 onComplete 尝试了一些东西,但 Success 似乎只接受 Int 而不是 Person。我想要以下内容:

future onComplete {
   case Success(result) => result
   case Failure(failure => doSomethingOnFailure(failure)
}

你有什么想法吗?

【问题讨论】:

  • 当你在两个演员之间交流时,你永远不应该使用询问。使用告诉然后收听响应消息。
  • 你检查pipe函数了吗? doc.akka.io/docs/akka/current/…
  • 你不能也不应该从一元上下文中提取价值,而是在其中进行组合。

标签: scala akka


【解决方案1】:

您希望通过处理另一条消息来处理响应。如果您可以将来自其他参与者的响应视为消息,那么只需使用 tell (!) 发送请求并在响应的接收方法中添加一个案例就足够了。

如果您需要避免混淆并行请求和响应,您可能需要使用 become 和 Stash 来确保一次只能有 1 个请求在进行中。当然,这会限制系统的吞吐量。

如果您想在将响应传递给receive 处理程序之前以某种方式“翻译”响应,pipe 模式可能会派上用场:

import akka.pattern.pipe

...
    val someIdentifier = ???
    (myActor2 ? request)
      .map(response => MyCommandWith(response, someIdentifier))
      .pipeTo(self)

这将收集ask 的结果,对其进行映射,然后将其作为消息发送给当前actor (self)。不过要非常小心,不要关闭 map 函数中的任何 actor 状态!

如果您希望邮件的原始发件人进一步处理结果或错误,则根本不需要pipe,但您可以使用forward 而不是ask。

【讨论】:

    【解决方案2】:

    将Future[Person] 转换为Person 并没有什么魔法。您必须在这个未来调用 Await 来提取结果,或者让这段代码返回 Future[Smth] 并将结果的提取委托给调用者。

    【讨论】:

      猜你喜欢
      • 2021-01-18
      • 2013-04-07
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多