为成功和失败绘制未来

mon*_*ack 26 scala

我有一个Future [T],我想在成功和失败方面映射结果.

比如,像

val future = ... // Future[T]
val mapped = future.mapAll { 
  case Success(a) => "OK"
  case Failure(e) => "KO"
}
Run Code Online (Sandbox Code Playgroud)

如果我使用mapflatmap,它只会映射成功期货.如果我使用recover,它只会映射失败的期货.onComplete执行回调但不返回修改后的未来.Transform会工作,但需要2个函数而不是部分函数,​​所以有点丑陋.

我知道我可以创造一个新的Promise,并用/ onComplete或完成它,但我希望有一些我遗漏的东西,这将允许我用一个PF做上述.onSuccessonFailure

esp*_*nhw 41

编辑2017-09-18:从Scala 2.12开始,有一个transform方法需要一个Try[T] => Try[S].所以你可以写

val future = ... // Future[T]
val mapped = future.transform {
  case Success(_) => Success("OK")
  case Failure(_) => Success("KO")
}
Run Code Online (Sandbox Code Playgroud)

对于2.11.x,以下仍适用:

AFAIK,你不能用一个PF直接做到这一点.并且transform变换Throwable => Throwable,所以这也无济于事.最接近你可以开箱即用:

val mapped: Future[String] = future.map(_ => "OK").recover{case _ => "KO"}
Run Code Online (Sandbox Code Playgroud)

也就是说,实现mapAll是微不足道的:

implicit class RichFuture[T](f: Future[T]) {
  def mapAll[U](pf: PartialFunction[Try[T], U]): Future[U] = {
    val p = Promise[U]()
    f.onComplete(r => p.complete(Try(pf(r))))
    p.future
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,我可以很容易地写出来,只是想知道这样的东西是否潜伏在某个地方. (3认同)
  • 嗨@espenhw,在你的答案的第2段中,你实际上是指`val mapped:Future [String] = future.map(_ =>"OK").recover {case _ =>"KO")` (2认同)

nma*_*mat 5

Scala 2.12开始,您可以transform用来映射两种情况:

future.transform {
      case Success(_) => Try("OK")
      case Failure(_) => Try("KO")
}
Run Code Online (Sandbox Code Playgroud)

您还可以transformWith,如果你喜欢使用Future的替代Try。检查文档以了解详细信息。