将Akka的未来[A]转换为未来[要么[例外,A]]

Kim*_*bel 6 scala future akka scala-2.9 scala-2.10

在Akka(或Scala 2.10中的标准库)中是否有一种方法可以将Future[A]可能失败的方法转换为Future[Either[Exception,A]]?我知道你可以写

f.map(Right(_)).recover {
  case e:Exception => Left(e)
}
Run Code Online (Sandbox Code Playgroud)

这似乎是一个如此常见的任务,我想知道我是否忽略了一些东西.我对Scala 2.9/Akka和Scala 2.10的答案很感兴趣.

Rol*_*uhn 12

缺少此方法的主要原因是它实际上没有良好的语义:静态类型Future[Either[Throwable, T]]不能确保未来不会失败,因此类型更改通常不会获得太多.

如果您控制处理这些未来的所有代码当然是有道理的,在这种情况下,自己添加它是微不足道的(这个名称是由于我在第一次喝咖啡之前发布的,可以随意用更好的东西替换):

implicit class FutureOps[T](val f: Future[T]) extends AnyVal {
  def lift(implicit ec: ExecutionContext): Future[Either[Throwable,T]] = {
    val p = promise[Either[Throwable,T]]()
    f.onComplete {
      case Success(s)  => p success Right(s)
      case Failure(ex) => p success Left(ex)
    }
    p.future
  }
}
Run Code Online (Sandbox Code Playgroud)

它与Akka 2.0期货非常相似,因此我将这个练习留给了读者.


Dyl*_*lan 0

无论如何,我认为你也不想这样做。Akka 2.0.5 的文档显示了这一点akka.dispatch.Future

\n\n
abstract def onComplete[U](func: (Either[Throwable, T]) \xe2\x87\x92 U): Future.this.type\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,未来可能失败的信息已经嵌入到了 的行为中Future[T]。这同样适用于 Scala 2.10 的 future,其中 future 可以完成为 a Try[T],其目的与 an 类似。Either[Exception, T]

\n\n
//in scala.concurrent.Future:\nabstract def onComplete[U]\n  (func: (Try[T]) \xe2\x87\x92 U)(implicit executor: ExecutionContext): Unit\n
Run Code Online (Sandbox Code Playgroud)\n