0

在 scala 并发包中,有一种onComplete方法在akka-http指令中不返回任何内容,它返回 Directive1。

这是唯一的区别吗?我有时对这两种方法感到困惑。

4

1 回答 1

1

这些方法的目标是不同的,但它们是相关的,因为 akka httponComplete旨在与 a 的完成一起工作,以Future完成请求的路由。

并发onComplete是在 a 上的一种方法Future,旨在在完成时执行某种副作用FutureFuture在likemap上还有很多其他方法flatMap,当您进行一系列转换时filter会产生另一种方法,但不会返回任何内容,并且在处理 that 时有点“死胡同” 。 FutureonCompleteFuture

一个使用onCompletewhile 的例子也展示了如何使用类似的东西map来改变Future如下:

val fut1 = Future{"1"} // A Future[String]
val fut2 = fut1.map(_.toInt) // Now a Future[Int]
fut2.onComplete{
  case util.Success(i) => println(s"success: $i")
  case util.Failure(ex) => ex.printStackTrace()
}

val badFut1 = Future{"A"}
val badFut2 = badFut.map(_.toInt) //Will be failed
badFut2.onComplete{
  case util.Success(i) => println(s"success: $i")
  case util.Failure(ex) => ex.printStackTrace()
}

在第一种情况下,我们将成功案例,因为“1”可以映射到一个 Int。在第二个示例中,我们将遇到错误情况,因为“A”不能映射到 Int。无论哪种方式,您都可以看到类似的东西map可以用来创造一个新的转变的未来,而onComplete可以用来根据它的最终结果做一些事情Future

在 Akka Http 中,您有时需要创建Route需要异步执行某些操作的定义。在这种情况下,您需要在该异步任务完成时完成路由。ARoute本身需要完全定义才能编译,因此您不能利用现有onComplete的 aFuture因为它不返回任何内容,并且会使它的定义Route不完整。因此,Akka 的人定义了一个onComplete指令,该指令将嵌入路由树并与 a 一起使用Future,返回 aDirective将完全定义树,Route而不是将其保持开放式结束Future.onComplete。一个例子:

val myRoute = 
  get{
    val fut = myActor ? "foo"
    onComplete(foo){
      case util.Success(_) => complete(StatusCodes.OK)
      case util.Failure(ex) => complete(StatusCodes.InternalServerError)
    }
  }

所以在这里,我向Actor使用提出请求ask (?),我得到了Future回复。我仍然需要制作完成Route我正在定义的东西。如果我做了这样的事情:

val myRoute = 
  get{
    val fut = myActor ? "foo"
    fut.onComplete{
      case util.Success(_) => complete(StatusCodes.OK)
      case util.Failure(ex) => complete(StatusCodes.InternalServerError)
    }
  }

它不起作用,因为onComplete这里是来自Future而不是指令的那个,并且返回Unit并且 myRoute不会被完全定义并且不会编译。

因此,该onComplete指令允许您根据 aRoute的完成来定义 a ,Future而您无法使用其本身预先存在onComplete的内容正确执行该指令。Future

于 2015-12-31T14:13:36.037 回答