Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compose a list of `Futures`?

Tags:

scala

future

I have a collection of Promises. I was looking for an effective way to compose the resulting Futures. Currently the cleanest way i found to combine them was to use a scalaz Monoid, like so:

  val promises = List(Promise[Unit], Promise[Unit], Promise[Unit])

  promises.map(_.future).reduce(_ |+| _).onSuccess {
    case a => println(a)
  }  

  promises.foreach(_.success(()))

Is there a clean way to do this that doesn't require scalaz?

The number of Futures in the collection will vary, and lots of intermediate collections is undesirable.

like image 667
Rich Henry Avatar asked Jun 30 '15 14:06

Rich Henry


2 Answers

You could use Future.traverse:

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{ Future, Promise }

val promises = List(Promise[Unit], Promise[Unit], Promise[Unit])
Future.traverse(promises)(_.future)

This will give you a Future[List[Unit]], which doesn't exactly qualify as "lots of intermediate collections", but isn't necessarily ideal, either. Future.reduce also works:

Future.reduce(promises.map(_.future))((_, _) => ())

This returns a Future[Unit] that will be satisfied when all of the futures are satisfied.

like image 122
Travis Brown Avatar answered Nov 10 '22 10:11

Travis Brown


Future.sequence is the method you want.

like image 44
lmm Avatar answered Nov 10 '22 10:11

lmm