假设我有一个函数func1
需要返回一个带有两个整数的Future
。这两个值中的每一个都由独立期货返回,如下所示:
def f1 = Future { 1 }
def f2 = Future { 2 }
def func1 : Future[(Int,Int)] = {
val future1 = f1
future1.map { result1 =>
result1 * 10
}
val future2 = f2
future2.map { result2 =>
result2 * 20
}
}
我需要future1
等到future2
结束(反之亦然)才能将结果作为(Int,Int)
返回。如何实现这一目标?
答案 0 :(得分:4)
这正是期货zip
方法的作用:
val futurePair: Future[(Int, Int)] = future1.zip(future2)
请注意,如果您之前没有实例化您的未来(例如,如果future1
和future2
是def
s,而不是val
s),那么这将运行两个并行的计算,而一个for comprehension(或flatMap
)会在开始第二个计算之前等待第一个计算成功。
答案 1 :(得分:1)
for
- 理解是最好的选择:
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import concurrent.ExecutionContext.Implicits.global
import concurrent.ExecutionContext.Implicits.global
scala> def f1 = Future{1}
f1: scala.concurrent.Future[Int]
scala> def f2 = Future{2}
f2: scala.concurrent.Future[Int]
scala> for {result1 <- f1; result2 <- f2} yield (result1 * 10, result2 * 20)
res0: scala.concurrent.Future[(Int, Int)] = scala.concurrent.impl.Promise$DefaultPromise@71f67a79
注意:这将按顺序运行两个Future
,而Cyrille Corpet's solution将并行运行它们。
答案 2 :(得分:1)
您可以对已经开始的期货使用for-understandnce:
val f1: Future[Int] = ???
val f2: Future[Int] = ???
val f3: Future[Int] = ???
val futureInts: Future[(Int, Int, Int)] = for {
result1 <- f1
result2 <- f2
result3 <- f3
} yield (result1, result2, result3)
如果期货被分配到lazy val
或defs
那么这将不起作用,因为期货不会开始(如果你在理解中开始期货,那么他们将按顺序执行)。以下是启动它们,然后使用for
等待它们的示例。
示例:
val f1: Future[Int] = Future {
println("starting f1")
Thread.sleep(1000)
1
}
val f2: Future[Int] = Future {
println("starting f2")
Thread.sleep(3000)
2
}
val f3: Future[Int] = Future {
println("starting f3")
Thread.sleep(2000)
3
}
val futureInts: Future[(Int, Int, Int)] = for {
result1 <- f1
result2 <- f2
result3 <- f3
} yield (result1, result2, result3)
futureInts.map {
case tuple => println(tuple)
}
输出:
starting f1 // These first
starting f3 // threes statements
starting f2 // happen right away.
(1,2,2) // Then this prints a three seconds later
在你的情况下,你可以这样做:
def func1 : Future[(Int,Int)] = {
// Start futures
val future1 = f1.map(_ * 10)
val future2 = f2.map(_ * 20)
// Wait for both futures, and return a tuple
for {
result1 <- future1
result2 <- future2
} yield (result1, result2)
}