2017-04-18 25 views
0

我有一个返回Future [Try [Option [Int]]]的方法。我想提取Int的值作进一步的计算。任何想法如何处理?在scala中处理未来[尝试[选项]]

+0

试图理解你为什么有前途[尝试[选项[INT]]。如果您同时选中“未来”,请尝试使用方法转到“选项”,然后您可以尝试将来自方法组合的结果映射到单个未来 –

+0

我同意@FabioFumarola。必须处理这种类型是非常不幸的。 – mfirry

+1

正确答案在很大程度上取决于您如何处理未来的错误案例,尝试和无。请在此添加更多详细信息。 – nmat

回答

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 
} 
1

转换Future[Try[Option[Int]]]Future[Int]

一个哈克的方式是不利的成果转化为失败的未来和flatMapping过。

将尝试失败转换为将来的失败,保留异常源自的信息尝试并将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" 
} 

现在在任何情况下,您都知道异常来自何处。如果没有发现异常,你知道未来和尝试是成功的,但选项是没有的。这样信息不会丢失,并且嵌套结构被平化为Future[Int]

现在结果类型为Future[Int]。只需使用map,flatMap,recover和recoverWith来编写进一步的动作。

2
future.map(_.map(_.map(i => doSomethingWith(i)))) 
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。 否则,你很高兴与其他有效的答案一起出发(我特别喜欢地图 - 地图一)。

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