我已经编写了这段代码并且可以正常工作
import scala.concurrent.{Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success, Random}
object TestFuture2 {
def bigCalc() : Future[Int] = Future {
Thread.sleep(1000)
40
}
}
object Main2 extends App {
val x = TestFuture2.bigCalc
val y = TestFuture2.bigCalc
val z = TestFuture2.bigCalc
val v = for {
r1 <- x
r2 <- y
r3 <- z
} yield (r1 + r2 + r3)
v onSuccess {
case x1 => println(x1)
}
System.in.read()
}
所以当我运行这个时,我得到 120。很好。
但我不喜欢我在 for 循环中对值求和
for {
r1 <- x
r2 <- y
r3 <- z
} yield (r1 + r2 + r3)
如果我将我的函数称为
val x = List(TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc)
现在我将如何总结?
我试过
x.reduce(_ + _)
但这不起作用。
scala> x.reduce(_ + _)
<console>:17: error: type mismatch;
found : scala.concurrent.Future[Int]
required: String
x.reduce(_ + _)
最佳答案
TL;DR 使用:Future.reduce(futures)(_ + _)
您的代码示例的主要问题是 Traversable#reduce
之间的混淆。和 Future#reduce
.您想使用第二个,但您使用第一个。Traversable#reduce
需要一个具有此签名的归约函数:Tuple2[Future[Int], Future[Int]] => Future[Int]
.Future#reduce
另一方面会自动为你解压存储在 future 中的值。它需要具有此签名的归约函数:Tuple2[Int, Int] => Int
.实用多了。
使用 Traversable#reduce
的示例功能:
val futures = List(TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc)
val reduced = futures.reduce((first: Future[Int], second: Future[Int]) => first.flatMap(firstResult => second.map(secondResult => secondResult + firstResult)))
使用
Future#reduce
的示例功能:val futures = List(TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc, TestFuture2.bigCalc)
val reduced = Future.reduce(futures)((first: Int, second: Int) => first + second)
您可以直接使用
Future#sequence
相反,因为这就是 Future#reduce
在引擎盖下使用它。但是你为什么要使用后者呢?如果您的列表为空,它将返回 future 的失败。因此,使用其中一种取决于您的要求。如果列表不应该为空,请使用 Future#reduce
.
关于Scala如何总结 future 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30792117/