Подтвердить что ты не робот

Как разрешить список фьючерсов в 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
4b9b3361

Ответ 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 для объединения многих фьючерсов вместе, а затем для использования обратного вызова для результата.