在scala中将Try转换为Future,并将recoverWith转换为Future

时间:2016-09-19 20:53:02

标签: scala concurrency

[编辑]

*被问到时我是新手。这就是答案:

Future.fromTry(Try( 1/0 ))

值得了解的其他事情(可能会错过 - 在检查时引导我):

Future.successful( 1/0 )

一旦达到就抛出。 Future.successful和Future.failure不仅是创建Future的便捷方式,它们还跳过执行上下文循环并按顺序进行评估。

[原始问题]

我有Try抛出异常。我希望Try成为Future所以我可以recoverWith

如果你不知道,请不要猜。

问题是,如何在不处理Try中的任何例外情况的情况下将Future转换为Try(仅在未来恢复中)?

请注意,需要Await来测试您未来的结果

代码示例演示了我的想法但是一旦达到它就会抛出(new RuntimeException("-------failed-------")就是我得到的)

val t = Try(throw new RuntimeException("my"))

val resF : Future[String] = if (t.isSuccess)
  Future.successful(t.get)
else
  Future.failed(new RuntimeException("-------failed-------"))

val resFWithRecover = resF.recoverWith{
  case NonFatal(e) =>
    Future.successful("recoveredWith")
}
Await.result(resFWithRecover, Duration("5s"))

4 个答案:

答案 0 :(得分:17)

  

...如何在不处理Try中的任何例外的情况下将Future转换为Try

使用Future.fromTry

scala> val t = Try(throw new RuntimeException("my"))
t: scala.util.Try[Nothing] = Failure(java.lang.RuntimeException: my)

scala> val resF = Future.fromTry(t)
resF: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise$KeptPromise@57cf54e1

scala> resF.recoverWith{
     |   case NonFatal(e) =>
     |     Future.successful("recoveredWith")
     | }
res5: scala.concurrent.Future[String] = scala.concurrent.impl.Promise$DefaultPromise@1b75c2e3

答案 1 :(得分:1)

如果您想要做的就是在上使用 recoverWith (有点像 flatMap ),则无需引入 Future >尝试对象。

您可以这样:

val t = Try[String](throw new RuntimeException("my"))
val u = t.recoverWith{
  case e => Success(s"ignoring exception ${e.getLocalizedMessage}")
}
u.foreach(println(_))

这会导致以下输出到控制台:

ignoring exception my

答案 2 :(得分:1)

 // you need to provide your try with type information in lhs
 // as the rhs is not providing any type info
 val t: Try[String] = Try(throw new RuntimeException("my"))

 // Now you can easily get a Future[String] from this Try[String]
 val f = Future.fromTry(t)

 // or you can use pattern matching
 val f2 = t match {
   case Success(str) => Future.succesful(str)
   case Failure(ex) => Future.failed(ex)
 }

答案 3 :(得分:0)

recoverWith上的Try也可以

使用map上的recoverTry方法分别生成Future.successfulFuture.failed,然后生成get上的Try < / p>

val future = 
 Try {
   throw new Exception("explosion")
 }.map { result =>
   Future.successful(result)
 }.recover { case th =>
   Future.failed(th)
 }.get

使用模式匹配

val future =  
 Try {
  throw new Exception("something")
 } match {
  case Success(value) => Future.successful(value)
  case Failure(th) => Future.failed(th)
 }