У меня есть несколько фьючерсов, которые могут быть выполнены в разное время, примерно так:

val results = task.getAssignedFiles map {
  file: File => Future[Result] {
    <heavy computation>
  }
}

Теперь я хочу перебрать results, как только один из входных фьючерсов завершится, в основном опросить все фьючерсы в результатах, пока один из них не будет завершен, произвести некоторую обработку и продолжить, пока все они не будут выполнены. Что-то типа:

while (!results.allCompleted) {
  one = results.firstCompletedFuture
  process(one)
}
0
UtsavShah 26 Ноя 2016 в 01:29

2 ответа

Лучший ответ

Вы ищете firstCompletedOf.

1
Reactormonk 25 Ноя 2016 в 22:35

Нет необходимости «зацикливаться» на списке Futures, чтобы принять меры по их завершению. Подход состоит в том, чтобы связать необходимую последовательность вычислений с помощью комбинаторов и ждать, пока все они не завершатся.

В терминах приведенного выше кода это можно было бы записать как:

val results:List[Future[Result] = task.getAssignedFiles map {
  file: File => Future[Result] {
    <heavy computation>
  }
} 
val processedResults:List[Future[ProcessedResult]] = results.map(result => process(result))
val finalResults:Future[List[ProcessedResult]] = Future.sequence(processedResults)

Обратите внимание, что все фьючерсы выполняются с момента их определения. sequence завершит работу в момент завершения последней из них.

1
maasg 25 Ноя 2016 в 22:59