Scala Future Composition
Future composition joins small Futures into one larger Future. It builds a new Future from old ones without waiting for each step by hand.
Map changes the value inside a Future
map makes a new Future from the old one. Awaiting the new Future gives 20.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val f = Future { 10 }
val doubled = f.map(x => x * 2)
val result = Await.result(doubled, 5.seconds)
println(result)FlatMap joins a Future that depends on the first value
The second Future is built from the first value. Awaiting the joined Future gives 8.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val f = Future { 5 }
val joined = f.flatMap(x => Future { x + 3 })
val result = Await.result(joined, 5.seconds)
println(result)A for-comprehension joins two Futures
Each generator gives a value, and yield combines them. Awaiting the combined Future gives 10.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val combined = for
a <- Future { 4 }
b <- Future { 6 }
yield a + b
val result = Await.result(combined, 5.seconds)
println(result)Example
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val step1 = Future { 3 }.map(x => x * 10)
val step2 = step1.flatMap(x => Future { x + 7 })
val result = Await.result(step2, 5.seconds)
println(result)Key points
- Map: f.map(x => x * 2) makes a new Future with the changed value.
- FlatMap: f.flatMap(x => Future { x + 1 }) joins a Future that depends on the first value.
- Chain: chained steps run in order, with each step using the last result.
- No wait: composition builds the combined Future, and Await waits only at the end.
- For: a for-comprehension over Futures is a short way to write flatMap and map.
In this example, map turns 3 into 30, then flatMap adds 7 to make 37. Only the final combined Future is awaited, and 37 is printed.
Note
map changes a value inside a Future. It never changes the original Future.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
What does f.map(x => x + 1) return?