【发布时间】:2017-10-24 02:29:45
【问题描述】:
例如你可以这样做:
Future(/* A */).flatMap(_ => Future(/* B */).flatMap(_ => Future(/* C */)))
这里 B 依赖于 A 来完成,有没有一种干净的方式来组合期货,以便 C 依赖于 A 和 B 来完成并且 A 和 B 可以并行运行?
【问题讨论】:
标签: scala parallel-processing future flatmap
例如你可以这样做:
Future(/* A */).flatMap(_ => Future(/* B */).flatMap(_ => Future(/* C */)))
这里 B 依赖于 A 来完成,有没有一种干净的方式来组合期货,以便 C 依赖于 A 和 B 来完成并且 A 和 B 可以并行运行?
【问题讨论】:
标签: scala parallel-processing future flatmap
我认为您正在寻找的是Future.sequence 方法,它允许您将Futures 的序列减少为单个Future。这是一个简单的例子:
def createFuture(name: String, sleep: Int): Future[(String, Int)] = {
Future({
println(s"Starting $name with sleep $sleep")
Thread.sleep(sleep)
println(s"After $name")
(name, sleep)
})
}
val rnd = new Random()
val fa = createFuture("A", rnd.nextInt(1000) + 500)
val fb = createFuture("B", rnd.nextInt(1000) + 500)
val ff = Future.sequence(List(fa, fb)).flatMap(l => createFuture("C" + l.map(_._2).sum, 100))
Await.result(ff, Duration.Inf)
其中一次运行的输出是:
从睡眠 1287 开始 B
从睡眠 550 开始 A
A之后
B 之后
以睡眠 100 启动 C1837
C1837 之后
如果你也想“快速失败”,可以考虑How to wait for several Futures的更复杂的答案
【讨论】:
Future(A).zipWith(Future(B))((_,_) => C)
【讨论】:
for yield 是这样做的干净方式,它等于flatMap,例如:
val futureA = Future {
// do something
}
val futureB = Future {
// do something
}
for {
_ <- futureA
_ <- futureB
} yield Future {
/* C */
}
初始futureA和futureB在for comprehensive之前,它们将并行运行。
【讨论】:
for 理解中启动它们,这只会按顺序运行它们。如果 futureA 和 futureB 类似于 Future[_] 而不是 () => Future[_] 那么这将正常工作