Попробуйте использовать что-то вроде этого:
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object Scratch {
def operation(i: Int): Future[Int] = {
Future.successful(i+1)
}
def main(args: Array[String]) {
val list = List(1,2,3,4)
val resultFuture = Future
.sequence(list.map(operation))
.transform(list => list.foldLeft(0)((x, y) => x+y), t => t)
println(Await.result(resultFuture, Duration.Inf))
}
}
Что происходит здесь:
- Ключевая идея заключается в
Future.sequence
. Это позволяет вам конвертировать сборку фьючерсов в будущее коллекции, а затем работать с этой коллекцией обычным способом. Поэтому мы используем его для упрощения нашей работы. Теперь у нас есть Future[List[Int]]
вместо List[Future[Int]]
- Нанесите наш
Future[List[Int]]
на Future[Int]
с использованием метода transform
. Собственно, здесь мы можем использовать любые преобразования, которые мы хотим, не только подсчитывая сумму.
- Мы ждем результата от
Future[Int]
с использованием контекста выполнения неявное по умолчанию
Единственная проблема с таким подходом может возникнуть, если ваша коллекция источник чрезвычайно велик, поэтому он не может соответствовать вашей куче, и вы хотите применить операции когда достаточно Futures of Int готовы (при условии, что порядок операций не важен). Если вы хотите это сделать, ответ должен быть немного сложнее.