目标是遍历列表,对列表的每个元素执行将来的操作,然后对这些未来操作返回的值求和。
我正在尝试仅使用不可变数据。
这样的事情:
list.foldRight(0)((obj,sum) => {
val c: Int = doFutureThing(obj)
c + sum // no good: c is a Future[Int]
}
答案 0 :(得分:2)
尝试使用类似的东西:
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object Scratch {
def operation(i: Int): Future[Int] = {
Future.successful(i+1)
}
def main(args: Array[String]) {
val list = List(1,2,3,4)
val resultFuture = Future
.sequence(list.map(operation))
.transform(list => list.foldLeft(0)((x, y) => x+y), t => t)
println(Await.result(resultFuture, Duration.Inf))
}
}
这里发生了什么:
Future.sequence
。它允许您将未来的集合转换为集合的未来,然后以通常的方式使用该集合进行操作。所以我们用它来简化我们的工作。现在我们有Future[List[Int]]
而不是List[Future[Int]]
Future[List[Int]]
方法将Future[Int]
映射到transform
。实际上,在这里我们可以使用我们希望的任何变换,而不仅仅是计算总和。Future[Int]
使用隐式默认执行上下文如果您的源集合非常大,可能会出现这种方法的唯一问题,因此它不适合您的堆,并且您希望在足够的Intures of Int准备就绪时应用操作(假设操作顺序不重要) )。如果你愿意,答案应该有点复杂。
答案 1 :(得分:1)
如果您从一系列项目开始......
val li = List(2, 4, 7) // List[Int]
...然后将其转换为期货集合......
import concurrent._
import concurrent.ExecutionContext.Implicits.global
val lfi = li.map(doFutureThing) // List[Future[Int]]
...然后你可以将它们减少到一个未来的项目。
val fi = Future.reduce(lfi)(_+_) // Future[Int]