You can use a for-comprehension for futures that have already started like this:
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)
If the futures were assigned to lazy val
s or defs
then this wouldn't work, because the futures would not have been started (if you start the futures inside the for comprehension, then they will be executed sequentially). Here is an example of starting them, and then waiting for them with for
.
Example:
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)
}
Output:
starting f1 // These first
starting f3 // threes statements
starting f2 // happen right away.
(1,2,2) // Then this prints a three seconds later
In your case you could do this:
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)
}