How can I make A future of future into one future object?
Solution 1
Short answer (English): flatMap dat sh!t
Shorter answer (Scala):
flatMap(identity)
Shortest answer: (Scala 2.12):
flatten
Long answer (Java):
flatMap(new Mapper<Future<X>>,Future<X>>() {
@Override public Future<X> apply(final Future<X> f) { return f; }
})
Solution 2
Note: Since Viktor Klang's 2012 answer, he recently (March 2016) added in his blog for scala 2.12:
Missing canonical combinators: flatten
Are you one of us
Future
-users who have grown tired of the oldflatMap(identity)
boilerplate for un-nesting Futures as in:
val future: Future[Future[X]] = ???
val flattenedFuture /*: Future[X] */ = future.flatMap(identity)
Then I have some great news for you! Starting with Scala 2.12
scala.concurrent.Future
will have a flatten-method with the following signature:
def flatten[S](implicit ev: T <:< Future[S]): Future[S]
Allowing you to write:
val future: Future[Future[X]] = ???
val flattenedFuture /*: Future[X] */ = future.flatten
Related videos on Youtube
Vincent Zou
(your about me is currently blank) click here to edit
Updated on June 04, 2022Comments
-
Vincent Zou almost 2 years
Env: Akka 2.1, scala version 2.10.M6, JDK 1.7,u5
Now is my problem: I have:
future1 = Futures.future(new Callable<Future<object>>(){...}); future2 = ? extends Object; Future.sequence(future1, future2).onComplete(...)
now in first line, I have a future of Future of object, is there any way to convert it into a Future while not blocking my current thread?
Is there any method in akka? As far as I checked, I havn't found any yet... First time to have a post....Sry for bad format and organize... :~P
-
Ali Hidim over 11 yearsThis doesn't look like Scala. Is there a reason for the Scala tag?
-
Vincent Zou over 11 yearsActually I am using akka 2.1 with scala lib for 2.10... sry for the confusion...
-
-
Vincent Zou over 11 yearsThanks for the answer....but why should we bother to use future when tried to make all the stuff async and say, let'em be executed in one thread??
-
Vishy over 11 yearsIt will still be executed in multiple threads (assuming you have a pool of more than one thread) just as it does now. This won't change the level of concurrency. If you have a pool of one, you could just use one task for everything and it could be much simpler.
-
Vincent Zou over 11 yearsyes, it would works well but if future1 is something of ,say, as is the problem in the question of the post, like Future<Future<...>>, and this main thread would be blocking such a long time which would be wasteful...and flatMap would make a new Future for Future<Future<...>> and give the call back to the original thread which would save more resources...But thanks for your suggestion any way. : )
-
Vincent Zou over 11 years: (...for flatMap, what if I make the inner Future (future1's callable funtion) failed using Futures.failed()? the flatMap would still be called? also, I don't want to recover it as, later I would like to make the future of sequence to be failed also....By the way, I am using java, funny for your English answer...: )
-
Vishy over 11 yearsThe waste is relatively trivial and using another approach you could waste far more IMHO. Also you don't need to keep wrap the Future objects. There is no reason it wouldn't be a plain future. In fact you could add everything it does into that task so there is not need to return anything at all.
-
Viktor Klang over 11 yearsI don't understand what you mean, easiest is probably just to try it out?