Создайте список из будущих результатов в Scala

Я хотел бы создать список результатов от нескольких "запросов" к ряду аккских актеров. Поэтому у меня есть список фьючерсов, и я хотел бы заполнить список этими результатами, а затем выполнить следующую операцию, когда все фьючерсы вернутся.

Пример. Тип объектов, которые я ожидаю создать готовый список, с

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

Список фьючерсов происходит от:

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

Что мне делать с futures чтобы создать список Foos?

val result = Await.result(futures.map(??????), 1 second).asInstanceOf[Foo]
1 ответ

Вы можете использовать Await.result и Future.traverse чтобы выполнить это.

-- 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 находится ключевое Future.traverse. Немного упрощая, он принимает значение Traversable[A] как первый аргумент и функцию A => Future[B] как второе, затем возвращает одно большое Future[Traversable[B]] которое будет завершено после того, как все отдельные Future закончатся и будут содержать все результаты B функции.

Обратите внимание, что если какое-либо из Future не работает, комбинированное Future также потерпит неудачу, что может быть или не быть тем, что вы хотите.

Кроме того, как правило, не рекомендуется использовать Await, как он вводит последовательное узкое место в ваших асинхронных Actors, вместо этого использовать pipeTo (или onComplete и т.д...), чтобы отправить результат в Future, как сообщения на ваш Actor, а затем обработать его соответствующим образом.

licensed under cc by-sa 3.0 with attribution.