用法scala Futures fallbackTo

时间:2015-10-05 05:53:45

标签: scala

我正在努力实现这样的目标。

val x: SomeType = ...    
val future: Future[SomeType] = Future {
  /*
   * Do some operation on x
   */
  x
}
future onComplete {
  case Success (x): x.status = "Success";
  case Failure (t):
    /*
     *  Here I want to write x.status = "Failed", But
     *  x is not available in this scope
     */
}

实现这一目标的有效方法是什么?

2 个答案:

答案 0 :(得分:0)

首先,您的代码似乎不是正确的Scala代码。案例匹配错误,在Future[x]中,您应该将类​​型提及为x,但应返回x本身,这应该是一个对象。

无论如何,你可以做下面的事情。当Future成功时,您可以将值记录在var中,如果失败,您仍然可以将值记录在var中。然而,这会给你的程序带来可变状态,很快就会失控。所以最好使用惯用的Scala代码(使用map,flatMap等),并完全避免使用状态。

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Random

object TestFuture {

  def main(args: Array[String]) {

    val future: Future[Int] = Future {
      if (Random.nextBoolean()) {
        10
      } else {
        throw new RuntimeException("Error")
      }
    }

//    future onComplete {
//      case Success(x) =>
//        println(x)
//      case Failure(t) =>
//        t.printStackTrace()
//    }

    future onSuccess {
      case x => println(s"SUCCESS: $x")
        // SUCCESS: 10
    }

    future onFailure {
      case x => println(s"FAILURE: $x")
        // FAILURE: java.lang.RuntimeException: Error
    }

    Await.ready(future, Duration.Inf)
  }

}

有多种方法可以做到。

同时检查以下内容:

答案 1 :(得分:0)

我认为你是从可变/程序的角度来看待它。最好像Monad一样使用它。你可以这样做:

case class Result(status: String)

val future: Future[Result] = Future { ... }

future map {
  result => result.copy(status = "Success")
} recover {
  case NonFatal(_) => Result("Failure")
}

这将始终返回具有正确状态的“成功”Future。也没有发生可变性。

我没有检查它是否编译;)