🎓 A1Learner
🔍
0 of 48 lessons completed

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?