【问题标题】:[Scala, Akka]: Future onComplete does not execute outside the sender[Scala,Akka]:Future onComplete 不会在发送方之外执行
【发布时间】:2018-04-17 14:47:03
【问题描述】:

我有一个路由类(发送者)、一个演员和一个助手类。从路由类中,我向参与者发送请求并获得 Future 响应。现在,我想将未来的响应传递给助手并在那里解决它。

TestRoute.scala:

val response: Future[Any] = (actor ? request) (timeout)
handler(response)(executionContext)

TestHelper.scala:

def handler(futureResponse: Future[Any])(implicit ec: ExecutionContext): StandardRoute = {
  onComplete(futureResponse) {
    case Success(s) => complete(s)
    case Failure(f) => reject
   }
}

问题在于,虽然onCompleteTestRoute.scala 中工作,但在移至TestHelper.scala 时它不起作用。任何想法可能是什么问题?

编辑:通过“它不起作用”,我的意思是整个 onComplete 函数被跳过并且根本不执行 - 没有错误,只是跳过。

【问题讨论】:

  • “它不起作用”到底是什么意思?
  • 您的问题需要更多上下文。据我所知,您的处理函数应该返回一个新的 Future[StandardRoute] 或 Unit 如果它有副作用。
  • 代码在我看来大致还可以,当您说它“只是跳过”时,您是如何执行它的?您是否尝试过添加打印/日志语句以确保两种情况都没有被评估?

标签: promise akka future akka-http


【解决方案1】:

您的代码中可能解释问题的“奇怪之处”很少。

1.考虑到futureResponse 的类型为Future[Any],我很惊讶您的代码甚至可以编译。 You should use mapToAny 转换为已知类型T。您现在构建代码的方式意味着Any 有一个Marshaller,它可能在TestRoute 中可用,但在TestHelper 中不可用。

2.responseval 而不是def 的事实意味着Actor 只会被查询一次,而不是每个请求一次。我想你想要这样的东西:

type Output = ???

val response: () => Future[Output] = 
  () => (actor ? request) (timeout) andThen (_.mapTo[Output])

这会改变处理程序的签名:

def handler(futureResponse: () => Future[Output])(implicit ec: ExecutionContext): StandardRoute = 
  onComplete(futureResponse()) {
    case Success(s) => complete(s)
    case Failure(f) => reject
  }

【讨论】:

    猜你喜欢
    • 2014-05-22
    • 1970-01-01
    • 2013-01-24
    • 2021-05-30
    • 1970-01-01
    • 2017-08-01
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多