Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve a list of futures in Scala

Tags:

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 (without blocking the server)

For example,

while(counter < numCalls){     val future = call(counter)     future.map{  x =>         //do stuff     }     counter += 1  }  //Now I want to execute code here after ALL the futures are resolved without  //blocking the server 
like image 892
user2816456 Avatar asked Nov 15 '13 23:11

user2816456


People also ask

How do you handle Future Scala?

Handle the result of a future with methods like onComplete , or combinator methods like map , flatMap , filter , andThen , etc. The value in a Future is always an instance of one of the Try types: Success or Failure.

What is Future sequence in Scala?

sequence takes a list of futures and transforms it into a single future of list in an asynchronous manner. For instance, assume that you have a list of independent jobs to be run simultaneously. In such a case, the list of futures can be composed into a single future of list using Future. sequence.

What is await result in Scala?

Await. result tries to return the Future result as soon as possible and throws an exception if the Future fails with an exception while Await. ready returns the completed Future from which the result (Success or Failure) can safely be extracted.

What is Future and promise in Scala?

The Promise is a writable, single-assignment container that completes a Future. The Promise is similar to the Future. However, the Future is about the read-side of an asynchronous operation, while the Promise is about the write-side.


1 Answers

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) 
like image 102
Leo Avatar answered Sep 30 '22 18:09

Leo