我是scala的新手,正在从事期货业务。因此,我有一个方法调用返回了Future,我的代码如下。
val futureResult = data.getState //this returns future
Await.result(id, 10 seconds) // waiting for future to complete
futureResult .onComplete({
case Success(result) => logger.info(s"resultis.. ${result}")
case Failure(exception) => exception.printStackTrace()
})
万一成功,我会在“结果”中获得理想的结果。但是我想在一个变量中获取结果的值,以将其传递给其他方法。我尝试了。
val finalResult = futureResult.onComplete({
case Success(result) => logger.info(s"resultis.. ${result}")
case Failure(exception) => exception.printStackTrace()
})
当我打印finalResult时,它为空。我该如何做才能具有结果价值,以便可以在其他地方使用
答案 0 :(得分:1)
当您开始使用Futures
和类似对象(根据其功能,统称为“ functors”或“ monads”)时,{check out this guide on functors with amazing animated pictures)会使用容器,具有特殊属性的盒子以及除非绝对必要,否则您不想从中“获得价值”。对于Future
,容器表示异步计算的值。
这意味着您应该使用map
,flatMap
和类似方法来使用计算结果。这样,您可以使整个计算保持异步。同样,代码中的其他函数应返回Future并应尽可能地携带它们。 Here is the Scala docs overview on Future
同时,如果您将Future
分配给变量,则是将“未来容器”分配给变量,而不是Future
将包含的值。这就是为什么在第二个示例中无法打印finalResult
的原因。
例如,您可以尝试:
def doSomething(value: String): Unit = ???
def calculateSomething(value: String): Boolean = ???
def calculateSomethingElse(value: Boolean): Future[Int] = ???
def myCode(...): Future[Int] = {
someCallThatReturnsFutureOfString(...)
.map { result =>
logger.info(s"Result is... $result")
// More computations with result
doSomething(result)
calculateSomething(result)
}
.flatMap { someCalculationResult =>
// More computations....
calculateSomethingElse(result)
}
}
如果要按照我的意愿处理异常,this other answer是您要寻找的东西,因为transform
允许您操纵成功的结果以及异常。 / p>
futureResult transform {
case Success(result) =>
println(s"Result is... $result")
// More computations with result
Success(calculateSomething(result))
case f @ Failure(exception) =>
exception.printStackTrace()
f
}
我知道,我好像没有回答你的问题。您可能会想“嘿,我想把价值发挥出来,并在其他地方使用它,这个家伙不是在告诉我”,但是除非有特殊的情况,否则这些价值将不被使用。转换为这种思维方式需要付出努力,一开始“看待如何完成”并不容易。
如果您仍然想获得价值,那么文森特的答案就是一个很好的答案。
答案 1 :(得分:0)
最好是这样:
val futureResult = data.getState.map(res => fn(res)) //this returns future
futureResult .onComplete({
case Success(result) => logger.info(s"resultis.. ${result}")
case Failure(exception) => exception.printStackTrace()
})
或至少:
val futureResult = data.getState //this returns future
futureResult .onComplete({
case Success(result) =>
logger.info(s"resultis.. ${result}")
fn(result)
case Failure(exception) => exception.printStackTrace()
})
但是,执行Await.result会使您发现,如果Future失败,可能会引发异常,并使程序崩溃。
您期望的“ finalResult”包含的是Await.result
返回的内容
请参见方法合同:
def result[T](awaitable : scala.concurrent.Awaitable[T], atMost : scala.concurrent.duration.Duration) : T