How can I make A future of future into one future object?

17,624

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 old flatMap(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
Share:
17,624

Related videos on Youtube

Vincent Zou
Author by

Vincent Zou

(your about me is currently blank) click here to edit

Updated on June 04, 2022

Comments

  • Vincent Zou
    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
      Ali Hidim over 11 years
      This doesn't look like Scala. Is there a reason for the Scala tag?
    • Vincent Zou
      Vincent Zou over 11 years
      Actually I am using akka 2.1 with scala lib for 2.10... sry for the confusion...
  • Vincent Zou
    Vincent Zou over 11 years
    Thanks 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
    Vishy over 11 years
    It 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
    Vincent Zou over 11 years
    yes, 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
    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
    Vishy over 11 years
    The 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
    Viktor Klang over 11 years
    I don't understand what you mean, easiest is probably just to try it out?