我有一个抽象的特征,对计算有一些要求,然后是对这些计算结果的一些函数。我想保持这个特性简单,以便于理解和测试。
trait Calculator {
def hardToCalculate1: Int
def hardToCalculate2: Int
def hardToCalculate3: Int
def result1 = hardToCalculate1 + hardToCalculate2
def result2 = hardToCalculate2 + hardToCalculate3
def result3 = hardToCalculate1 + hardToCalculate3
}
当我实例化 aCalculator
时,我将使用 Futures 来计算这些hardToCalculate
值。假设它们看起来像这样:
def f1 = future {
println("calculating 1")
1
}
def f2 = future {
println("calculating 2")
2
}
def f3 = future {
println("calculating 3")
3
}
所以,我可以构造一个Future[Calculator]
这样的:
val myCalc = for {
m1 <- f1
m2 <- f2
m3 <- f3
} yield new Calculator {
lazy val hardToCalculate1 = m1
lazy val hardToCalculate2 = m2
lazy val hardToCalculate3 = m3
}
然后,我可能会myCalc
这样使用:
myCalc onComplete {
case Success(calc) => println("Result: " + calc.result1)
}
但是当我这样做时,我得到了这个:
calculating 1
calculating 2
calculating 3
Result: 3
如果我正在做的计算确实需要它们,我只想执行这些期货。尽管我用 s 声明了hardToCalculate
s lazy val
,但所有三个都是在Future[Calculator].onComplete
执行时计算的。
一种方法是这样的:
val calculator = new Calculator {
lazy val hardToCalculate1 = Await.result(f1, 10 seconds)
lazy val hardToCalculate2 = Await.result(f2, 10 seconds)
lazy val hardToCalculate3 = Await.result(f3, 10 seconds)
}
println("result: " + calculator.result1)
这产生了我想要的:
calculating 1
calculating 2
result: 3
但现在我有所有的Await
障碍。我真正想要的是以Future[Calculator]
一种懒惰的方式执行期货。如果不将 Futures 引入我的Calculator
特征,这可能吗?关于如何在这里获得我想要的东西的任何其他建议?