7

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

f.map(Right(_)).recover {
  case e:Exception => Left(e)
}

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

4

3 回答 3

13

缺少此方法的主要原因是它实际上并没有良好的语义:静态类型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
  }
}

它与 Akka 2.0 期货的工作方式非常相似,因此我将这个练习留给读者。

于 2013-01-05T09:20:08.967 回答
4

这种转换的另一个版本(在标准 Scala 中):

f.transform(tryResult => Success(tryResult.toEither))
于 2018-09-27T11:59:32.273 回答
0

我不认为你会想要这样做。Akka 2.0.5 的文档显示akka.dispatch.Future

abstract def onComplete[U](func: (Either[Throwable, T]) ⇒ U): Future.this.type

所以 Future 可能失败的信息已经嵌入到Future[T]. 这同样适用于 Scala 2.10 的 futures,future 可以完成为 a Try[T],其目的类似于Either[Exception, T].

//in scala.concurrent.Future:
abstract def onComplete[U]
  (func: (Try[T]) ⇒ U)(implicit executor: ExecutionContext): Unit
于 2013-01-05T05:48:59.493 回答