Scala Future Sequencing
Future sequencing turns a list of Futures into one Future of a list. It waits for every job and keeps the results in the same order as the list.
Sequence turns a list of Futures into one Future
Three Futures become one Future holding a list. Awaiting it gives the list in order.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val jobs = List(Future { 1 }, Future { 2 }, Future { 3 })
val combined = Future.sequence(jobs)
val result = Await.result(combined, 5.seconds)
println(result)Traverse maps and sequences in one step
Each number is mapped to a Future ten times as large. The combined list holds 10, 20, and 30.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val combined = Future.traverse(List(1, 2, 3))(x => Future { x * 10 })
val result = Await.result(combined, 5.seconds)
println(result)A sequenced list is an ordinary list
Once awaited, the list can be used like any list. Its sum here is 9.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val combined = Future.sequence(List(Future { 2 }, Future { 3 }, Future { 4 }))
val results = Await.result(combined, 5.seconds)
println(results.sum)Example
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
@main def main(): Unit =
val combined = Future.traverse(List(10, 20, 30))(x => Future { x + 5 })
val totals = Await.result(combined, 5.seconds)
println(totals)
println(totals.sum)Key points
- Sequence: Future.sequence turns a list of Futures into one Future of a list.
- Order: the results stay in list order, matching the order of the input list.
- Traverse: Future.traverse maps each item to a Future and then sequences the results.
- Wait once: Await waits once on the combined Future, not on each job.
- Empty: sequencing an empty list gives an empty list.
In this example, traverse adds 5 to each price and sequences the three Futures into one. The awaited list is printed, then its sum 75 is printed.
Note
if any Future in the list fails, the sequenced Future fails too.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
What does Future.sequence do?