I have some code like
//all data have different types
val data1Future = loadData1(params)
val data2Future = loadData2(params)
val data3Future = loadData3(params)
def saveResult(rez): Future[_] = ???
data1Future.flatMap { data1 =>
data2Future.flatMap { data2 =>
data3Future.flatMap { data3 =>
//do some computation
//several rows and several vals
val rez = ???
saveResult(rez)
}
}
}
But it is a litle bit ugly :) Unfortunatelly, I can't use for comprehension since I need something like "flatYield"
for {
data1 <- data1Future
data1 <- data1Future
data1 <- data1Future
} flatYield {
//do some computation
//several rows and several vals
val rez = data1 + data2 + data3
saveResult(rez)
}
Do you know pattern that is such elegant as "for comprehension" but with flatMap instead of map at the end of the chain?
You can do this:
This translates to
which is isomorphic to your code.
Using a for comprehension (like your stated goal) is equivalent to the defining the futures in a sequence of flatMap operations will wait for the result of each future before going to the next. Since your futures don't depend on each other you can start them all without waiting for the previous one to complete - this is what you have done in your initial example.
Start them concurrently and store the futures in a sequence use Future.sequence to turn the collection of futures into a single Future that won't complete until ALL of them complete (or any one of them fails). Then save your result when the future Completes.
It seems like you just want another line within your for-comprehension, and all of that "other computation" should go within another function to keep things clean:
Alternatively you can use something like this: