我有一个返回Future [Try [Option [Int]]]的方法。我想提取Int的值以进行进一步的计算。知道如何处理吗?
答案 0 :(得分:2)
future.map(_.map(_.map(i => doSomethingWith(i))))
答案 1 :(得分:1)
只需map
未来并使用匹配案例来处理不同的案例:
val result: Future[Try[Option[Int]]] = ???
result.map {
case Success(Some(r)) =>
println(s"Success. Result: $r")
//Further computation here
case Success(None) => //Success with None
case Failure(ex) => //Failed Try
}
答案 2 :(得分:1)
将Future[Try[Option[Int]]]
转换为Future[Int]
一种hacky方式是将不利的结果转换为失败的未来和flatMapping结束。
将尝试失败转换为Future失败,保留异常来自Try的信息并将None转换为NoneFound异常。
val f: Future[Try[Option[Int]]] = ???
case class TryException(ex: Throwable) extends Exception(ex.getMessage)
case object NoneFound extends Exception("None found")
val result: Future[Int] = f.flatMap {
case Success(Some(value)) => Future.successful(value)
case Success(None) => Future.failed(NoneFound)
case Failure(th) => Future.failed(TryException(th))
}
result.map { extractedValue =>
processTheExtractedValue(extractedValue)
}.recover {
case NoneFound => "None case"
case TryException(th) => "try failures"
case th => "future failures"
}
现在,在每种情况下,您都知道异常的起源。如果是NoneFound异常,你知道Future和Try是成功的但是选项是none。这样,信息不会丢失,嵌套结构将被展平为Future[Int]
。
现在结果类型为Future[Int]
。只需使用map,flatMap,recover和recoverWith来构成进一步的动作。
答案 3 :(得分:0)
如果你想使用cats,你可以做一些有趣的事情(对某些有趣的定义):
import scala.concurrent._
import scala.util._
import scala.concurrent.ExecutionContext.Implicits.global
import cats.Functor
import cats.instances.option._
import cats.implicits._
val x = Future { Try { Some(1) } } // your type
Functor[Future].compose[Try].compose[Option].map(x)(_ + 2)
仅在您熟悉猫或scalaz时才建议这样做。 否则,你很高兴在这里找到任何其他有效答案(我特别喜欢map-map-map)。
答案 4 :(得分:0)
如果你真的关心提取,请看看这个,否则请查看@pamu的答案,了解你如何实际使用你的未来。
假设您的未来值为result
。
Await.ready(result, 10.seconds).value.get.map { i => i.get}.get
显然,这不会通过你的失败和无案件并且会抛出异常并且不建议等待。
因此,如果您想处理失败和无案例 - >
val extractedValue = Await.ready(f, 10.seconds).value.get match {
case Success(i) => i match {
case Some(value) => value
case None => println("Handling None here")
}
case Failure(i) => println("Handling Failure here")
}