How to flatten a List of Futures in Scala
23,133
Future.sequence
takes a List[Future[T]]
and returns a Future[List[T]]
.
You can do
Future.sequence(f)
and then use map
or onComplete
on it to access the list of values.
Author by
mljohns89
Updated on July 07, 2020Comments
-
mljohns89 almost 4 years
I want to take this val:
val f = List(Future(1), Future(2), Future(3))
Perform some operation on it (I was thinking flatten)
f.flatten
And get this result
scala> f.flatten = List(1,2,3)
If the flatten method isn't appropriate here, that's fine. As long as I get to the result.
Thanks!
-
mljohns89 over 9 yearsThis is the output I'm getting: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise@3227f076 Is this expected? It is transforming a List[Future[T]] into a Future[List[T]]. But I was expecting something along the lines of: scala.concurrent.Future[List[Int]] = Future(List(1,2,3)) Thanks!
-
Gabriele Petronella over 9 yearsYes, it's a
Future
. Now you can handle it (either map, use onComplete or anything you want). The result inside theFuture
will be your list in case of success -
lmm over 9 years
Future
doesn't normally print what's inside it (that would mean blocking). If you doFuture(1)
, you'll get something that looks likescala.concurrent.impl.Promise$DefaultPromise@78393fdb
. For testing you can use something likeAwait.result(f, 2.seconds)
. -
Gabriele Petronella over 9 years@mikejones1477 it's almost always preferable not to block. Consider handling the result asynchronously
-
mljohns89 over 9 yearsYes. I wasn't planning on blocking for my final result. But in the interest of learning, I'd like to ask what you mean about asynchronously?
-
Gabriele Petronella over 9 yearsI mean in a non-blocking way. Mapping over a future is already asynchronous, since the code will run eventually in the future (if the computation has success)