Вопрос

I would like to create a list of results from several "asks" to a series of Akka actors. So essentially I have a list of futures, and I would like to fill a list with those results, and then perform the next operation when all futures have returned.

Example: The type of objects I expect to create the finished list with

case class Foo(id:Int, message:String)

The list of futures comes from:

val futures =
        context.children.map {
          child => {
            (child ? ("foo"))(5 seconds)
          }
        }

What do I do with futures to create a list of Foos?

val result = Await.result(futures.map(??????), 1 second).asInstanceOf[Foo]
Это было полезно?

Решение

You can use Await.result and Future.traverse to accomplish this.

-- create one big Future containing all the responses
val future = Future.traverse(context.children) { c => (c ? "foo")(5 seconds) }

-- now wait for it to return
val result = Await.result(future, 1 second)

Future.traverse is key here. Slightly simplifying, it takes Traversable[A] as it's first argument and a function A => Future[B] as it's second, then returns one big Future[Traversable[B]] which will complete once all the individual Futures complete and contain all the B results of the function.

Note that if any of the Futures fail, the combined Future will fail as well, which may or may not be what you want.

Also, it's usually recommended not to use Await as it introduces a sequential bottleneck in your asynchronous Actors, instead use pipeTo (or onComplete etc...) to send the result of the Future as a message to your Actor and then handle it accordingly.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top