【发布时间】:2013-08-02 03:14:30
【问题描述】:
描述我的问题的简单代码示例:
import scala.util._
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
class LoserException(msg: String, dice: Int) extends Exception(msg) { def diceRoll: Int = dice }
def aPlayThatMayFail: Future[Int] = {
Thread.sleep(1000) //throwing a dice takes some time...
//throw a dice:
(1 + Random.nextInt(6)) match {
case 6 => Future.successful(6) //I win!
case i: Int => Future.failed(new LoserException("I did not get 6...", i))
}
}
def win(prefix: String): String = {
val futureGameLog = aPlayThatMayFail
futureGameLog.onComplete(t => t match {
case Success(diceRoll) => "%s, and finally, I won! I rolled %d !!!".format(prefix, diceRoll)
case Failure(e) => e match {
case ex: LoserException => win("%s, and then i got %d".format(prefix, ex.diceRoll))
case _: Throwable => "%s, and then somebody cheated!!!".format(prefix)
}
})
"I want to do something like futureGameLog.waitForRecursiveResult, using Await.result or something like that..."
}
win("I started playing the dice")
这个简单的例子说明了我想要做什么。基本上,如果用一句话来说,我想等待一些计算的结果,当我对先前的成功或失败的尝试进行不同的操作时。
那么你将如何实现win 方法?
我的“现实世界”问题,如果有什么不同的话,是使用 dispatch 进行异步 http 调用,我想在前一个结束时继续进行 http 调用,但是在前一个 http 调用是否成功时操作会有所不同与否。
【问题讨论】:
-
您应该将整个
aPlayThatMayFail包装在一个future { ... }调用中,而不是调用Thread.sleep,然后在一段时间后返回一个立即可用的Future——否则您未来计算的阻塞部分将不会在未来运行,并且会像任何基于非未来的代码一样阻止调用者。 -
对 :) 无论如何,这只是为了说明这个想法......
-
是的,我怀疑是这样,但以防万一:)