Как разрешить список фьючерсов в Scala
У меня есть вызов, который возвращает будущее.
Тем не менее, мне нужно сделать n звонков, чтобы я вернул n фьючерсов. Мне интересно, как я буду получать фьючерсы для всех, прежде чем продолжить (без блокировки сервера).
Например,
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
Ответы
Ответ 1
Вы можете использовать Future.sequence(futureList)
для преобразования a List[Future[X]]
в Future[List[X]]
. И так как последнее просто просто Future
, вы можете дождаться его завершения с помощью Await.ready
или подобных помощников.
Таким образом, вам нужно будет сохранить список фьючерсов, которые вы создаете. Что-то вроде:
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)
который вы также можете написать как:
val futures = (1 to numCalls).map(counter => {
f = call(counter)
f.map(x => ...)
f
})
Await.ready(Future.sequence(futures), Duration.Inf)
Ответ 2
Немного более функциональный:
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)
Ответ 3
Я считаю, что вы хотите что-то сделать после завершения Futures, например. обратный вызов, без блокировки исходного вызова? Затем вы должны сделать что-то вроде этого:
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
Таким образом, вы не блокируете вызов с ожиданием, но вы все еще ожидаете завершения всех Futures и затем сделаете что-нибудь по всем результатам. Ключевыми аспектами являются использование Future.sequence для объединения многих фьючерсов вместе, а затем для использования обратного вызова для результата.