处理未来[尝试[选项]]在scala中

时间:2017-04-18 15:30:08

标签: scala scala-collections

我有一个返回Future [Try [Option [Int]]]的方法。我想提取Int的值以进行进一步的计算。知道如何处理吗?

5 个答案:

答案 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")
}