I have a call that returns a Future. However, I need to make n calls so I will get back n futures. I am wondering how I would get the futures to all resolve before proceeding (w
I take it that you want to do something after the Futures are finished ,eg. a callback, without blocking the original call? Then you should do something like this:
val futures = for (...) yield {
future {
...
}
}
val f = Future sequence futures.toList
f onComplete {
case Success(results) => for (result <- results) doSomething(result)
case Failure(t) => println("An error has occured: " + t.getMessage)
}
http://docs.scala-lang.org/overviews/core/futures.html
So you don't block with an await call, but you still wait for all Futures to complete and then do something on all results. The key aspects is using Future.sequence to join a lot of futures together and then to use a callback to act on the result.
You can use Future.sequence(futureList)
to convert a List[Future[X]]
to a Future[List[X]]
. And since the latter is just a simple Future
, you can wait for it to finish with the help of the Await.ready
or similar helpers.
So you would have to keep a list of the futures you generate. Something like:
val futures = new ListBuffer[Future[X]]
while(counter < numCalls) {
val future = call(counter)
futures += future
future.map { x =>
//do stuff
}
counter += 1
}
val f = Future.sequence(futures.toList)
Await.ready(f, Duration.Inf)
which you could also write as:
val futures = (1 to numCalls).map(counter => {
f = call(counter)
f.map(x => ...)
f
})
Await.ready(Future.sequence(futures), Duration.Inf)
A little more functional:
val futures = for {
c <- 0 until 10
} yield {
val f = call(c)
f onSuccess {
case x =>
// Do your future stuff with x
}
f
}
Future.sequence(futures)