🎓 A1Learner
🔍
0 of 45 lessons completed

Future Traversal

Future traversal is the turning of a list of futures into one future. The single future holds a list of all the results in order.

traverse turns inputs into results

Each input is multiplied by ten. The results are collected in input order.

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
  val all = Future.traverse(List(2, 3, 4))(x => Future(x * 10))
  println(Await.result(all, 5.seconds))

sequence collects existing futures

Three futures already exist. Sequence gathers their values into one list.

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
  val futures = List(Future(1), Future(2), Future(3))
  println(Await.result(Future.sequence(futures), 5.seconds))

traverse keeps order with words

Each word is replaced by its length. The lengths stay in word order.

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
  val all = Future.traverse(List("cat", "hello"))(s => Future(s.length))
  println(Await.result(all, 5.seconds))

Example

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
  val all = Future.traverse(List(10, 20, 30))(x => Future(x + 5))
  val total = all.map(values => values.sum)
  println(Await.result(total, 5.seconds))

Key points

  • Traverse: Traverse builds one future from a list of inputs by running a function on each input.
  • Use Future.traverse to turn each input into a future and collect the results.
  • Use Future.sequence to collect a list of futures that already exists.
  • Order: The collected results stay in the same order as the inputs.
  • Failure: If one future fails, the collected future fails as well.

In this example, traverse turns 10, 20 and 30 into 15, 25 and 35. Then map sums those values to 75, and the program prints that total.

Note

Traverse starts a future for every input, so the inputs run without waiting for each other.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

What does Future.sequence(List(Future(2), Future(4))) give when awaited?