使用scala期货回退到

使用scala期货回退到,scala,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

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

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
     */
}

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

首先,您的代码似乎不是正确的Scala代码。大小写匹配错误,在将来的[x]中,应该将类型提到x,但返回x本身,它应该是一个对象

无论如何,你可以做下面的事情。当未来成功时,您可以将该值记录在一个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)
  }

}
做这件事的方法不止一种

同时检查以下各项:


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

case class Result(status: String)

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

future map {
  result => result.copy(status = "Success")
} recover {
  case NonFatal(_) => Result("Failure")
}
这将始终以正确的状态返回成功的未来。也没有发生可变性


我没有检查它是否编译

“case Failure”意味着“Future{…}”中的代码抛出了一个异常,因此没有办法让x返回,因为它没有返回,即使您使用常规方法,如fallBackTo、recover、recoverWith。无论如何,我不建议在这里使用可变数据。不管你的问题是什么,没有这个都可以解决。对不起。你的第一段是我的意思,直到现在才意识到。更新了问题。