In the code below x is type Future[Future[Int]] and I need to flatten it to become Future[Int]. How is this possible?
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield {
val future = times(x1,x2)
future.map { result => result * 2 }
}
Use the same for-comprehension. As times returns Future taking input x1 and x2. You can use same for-comprehension to extract the value out of the future.
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
result <- times(x1,x2)
} yield (result * 2)
Remember for-comprehension is a syntactic sugar for flatMaps and one final map
The whole thing can be written as
Future { 1 }.flatMap { x1 => Future { 2 }.flatMap { x2 => times(x1, x2).map { result => result * 2 }}}
Warning: As you are creating data independent futures inline (inside the for-comprehension or inside the flatMap). These futures will execute sequentially.
As first and second futures are data independent. They can be executed parallelly if you have created them outside the for-comprehension or flatMap.
Flatten futures
Use flatMap to convert Future[Future[Int]] into Future[Int]
def times(a:Int, b:Int) = Future { a * b }
val x = (for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield {
val future = times(x1,x2)
future.map { result => result * 2 }
}).flatMap(identity) // <--- notice flatMap here around the for-comprehension
For clarity above code can be re-written as
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield times(x1,x2).map(_ * 2)
val finalResult = x.flatMap(identity)
scala> :paste
// Entering paste mode (ctrl-D to finish)
def times(a:Int, b:Int) = Future { a * b }
val x = for {
x1 <- Future { 1 }
x2 <- Future { 2 }
} yield times(x1,x2).map(_ * 2)
val finalResult = x.flatMap(x => x)
// Exiting paste mode, now interpreting.
scala> finalResult
res0: scala.concurrent.Future[Int] = Future(Success(4))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With