Sie können stattdessen ein Verständnis wie folgt verwenden:
val fut1 = Future{...}
val fut2 = Future{...}
val fut3 = Future{...}
val aggFut = for{
f1Result <- fut1
f2Result <- fut2
f3Result <- fut3
} yield (f1Result, f2Result, f3Result)
In diesem Beispiel werden die Futures 1, 2 und 3 parallel gestartet. Dann warten wir zum Verständnis, bis die Ergebnisse 1 und dann 2 und dann 3 verfügbar sind. Wenn entweder 1 oder 2 fehlschlägt, werden wir nicht mehr auf 3 warten. Wenn alle 3 erfolgreich sind, enthält der aggFut
Wert ein Tupel mit 3 Slots, das den Ergebnissen der 3 Futures entspricht.
Wenn Sie nun das Verhalten benötigen, bei dem Sie aufhören möchten zu warten, wenn sagen, dass fut2 zuerst fehlschlägt, werden die Dinge etwas schwieriger. Im obigen Beispiel müssten Sie warten, bis fut1 abgeschlossen ist, bevor Sie feststellen, dass fut2 fehlgeschlagen ist. Um das zu lösen, können Sie Folgendes versuchen:
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)
}
Dies funktioniert nun korrekt, aber das Problem besteht darin, zu wissen, welche Future
zu entfernen sind, Map
wenn eine erfolgreich abgeschlossen wurde. Solange Sie eine Möglichkeit haben, ein Ergebnis richtig mit der Zukunft zu korrelieren, die dieses Ergebnis hervorgebracht hat, funktioniert so etwas. Es entfernt nur rekursiv abgeschlossene Futures von der Karte und ruft dann Future.firstCompletedOf
die verbleibenden auf, Futures
bis keine mehr übrig sind, und sammelt die Ergebnisse auf dem Weg. Es ist nicht schön, aber wenn Sie wirklich das Verhalten brauchen, über das Sie sprechen, dann könnte dies oder etwas Ähnliches funktionieren.