In some cases it is necessary to calculate a variable amount of values on separate Futures. Assume to have a List[Future[Int]]
, but instead a List[Int]
needs to be processed. Then the question is how to turn this instance of List[Future[Int]]
into a Future[List[Int]]
. For this purpose there is the sequence
method on the Future
companion object.
def listOfFuture: List[Future[Int]] = List(1,2,3).map(Future(_))
def futureOfList: Future[List[Int]] = Future.sequence(listOfFuture)
In general sequence
is a commonly known operator within the world of functional programming that transforms F[G[T]]
into G[F[T]]
with restrictions to F
and G
.
There is an alternate operator called traverse
, which works similar but takes a function as an extra argument. With the identity function x => x
as a parameter it behaves like the sequence
operator.
def listOfFuture: List[Future[Int]] = List(1,2,3).map(Future(_))
def futureOfList: Future[List[Int]] = Future.traverse(listOfFuture)(x => x)
However, the extra argument allows to modify each future instance inside the given listOfFuture
. Furthermore, the first argument doesn't need to be a list of Future
. Therefore it is possible to transform the example as follows:
def futureOfList: Future[List[Int]] = Future.traverse(List(1,2,3))(Future(_))
In this case the List(1,2,3)
is directly passed as first argument and the identity function x => x
is replaced with the function Future(_)
to similarly wrap each Int
value into a Future
. An advantage of this is that the intermediary List[Future[Int]]
can be omitted to improve performance.