대신 다음과 같이 이해를 위해 사용할 수 있습니다.
val fut1 = Future{...}
val fut2 = Future{...}
val fut3 = Future{...}
val aggFut = for{
f1Result <- fut1
f2Result <- fut2
f3Result <- fut3
} yield (f1Result, f2Result, f3Result)
이 예에서 선물 1, 2, 3은 병렬로 시작됩니다. 그런 다음 for comprehension에서 결과 1, 2, 3이 나올 때까지 기다립니다. 1 또는 2가 실패하면 더 이상 3을 기다리지 않습니다. 3 개가 모두 성공하면 aggFut
val은 3 개의 Future의 결과에 따라 3 개의 슬롯이있는 튜플을 보유합니다.
이제 fut2가 먼저 실패한다고 말하면 기다리지 않으려는 동작이 필요하면 상황이 조금 더 까다로워집니다. 위의 예에서 fut2가 실패했음을 인식하기 전에 fut1이 완료 될 때까지 기다려야합니다. 이를 해결하기 위해 다음과 같이 시도 할 수 있습니다.
val fut1 = Future{Thread.sleep(3000);1}
val fut2 = Promise.failed(new RuntimeException("boo")).future
val fut3 = Future{Thread.sleep(1000);3}
def processFutures(futures:Map[Int,Future[Int]], values:List[Any], prom:Promise[List[Any]]):Future[List[Any]] = {
val fut = if (futures.size == 1) futures.head._2
else Future.firstCompletedOf(futures.values)
fut onComplete{
case Success(value) if (futures.size == 1)=>
prom.success(value :: values)
case Success(value) =>
processFutures(futures - value, value :: values, prom)
case Failure(ex) => prom.failure(ex)
}
prom.future
}
val aggFut = processFutures(Map(1 -> fut1, 2 -> fut2, 3 -> fut3), List(), Promise[List[Any]]())
aggFut onComplete{
case value => println(value)
}
이제 이것은 올바르게 작동하지만 문제는 성공적으로 완료되었을 때 Future
제거 할 항목을 아는 데서 발생 Map
합니다. 결과를 해당 결과를 생성 한 Future와 적절하게 연관시킬 수있는 방법이있는 한, 이와 같은 것이 작동합니다. 맵에서 완료된 Future를 계속 제거 Future.firstCompletedOf
하고 남은 Futures
것이 없을 때까지 계속 호출 하여 결과를 수집합니다. 예쁘지는 않지만 당신이 말하는 행동이 정말로 필요하다면 이것 또는 비슷한 것이 작동 할 수 있습니다.