Ich suche nach einer Möglichkeit, eine Liste von Futures beliebiger Länge in eine Future of List umzuwandeln. Ich benutze Playframework, also möchte ich letztendlich wirklich ein Future[Result]
, aber um die Dinge einfacher zu machen, sagen wir einfach. Future[List[Int]]
Der normale Weg, dies zu tun, wäre zu verwenden, Future.sequence(...)
aber es gibt eine Wendung ... Die Liste, die ich normalerweise bekomme, hat Es gibt ungefähr 10 bis 20 Futures, und es ist nicht ungewöhnlich, dass eine dieser Futures fehlschlägt (sie stellen externe Webdienstanfragen). Anstatt alle erneut versuchen zu müssen, falls einer von ihnen ausfällt, möchte ich in der Lage sein, diejenigen zu finden, die erfolgreich waren, und diese zurückzugeben.
Das Folgende funktioniert beispielsweise nicht
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Success
import scala.util.Failure
val listOfFutures = Future.successful(1) :: Future.failed(new Exception("Failure")) ::
Future.successful(3) :: Nil
val futureOfList = Future.sequence(listOfFutures)
futureOfList onComplete {
case Success(x) => println("Success!!! " + x)
case Failure(ex) => println("Failed !!! " + ex)
}
scala> Failed !!! java.lang.Exception: Failure
Anstatt die einzige Ausnahme zu bekommen, möchte ich in der Lage sein, die 1 und 3 da rauszuziehen. Ich habe es versucht Future.fold
, aber das ruft anscheinend nur Future.sequence
hinter die Kulissen.
Vielen Dank im Voraus für die Hilfe!
.recover
war in der Tat das fehlende Stück für mich._.collect{ case Success(x) => x}
anstatt in Art von_.filter(_.isSuccess)
loszuwerden .Try
futureListOfSuccesses
.recover(x => Failure(x))
ist nicht gültig, verwenden Sie.recover({case e => Failure(e)})
stattdessenScala 2.12 hat eine Verbesserung gegenüber
Future.transform
einer Antwort mit weniger Codes.quelle
Ich habe Kevins Antwort ausprobiert und bin auf einen Fehler in meiner Version von Scala (2.11.5) gestoßen ... Ich habe das korrigiert und ein paar zusätzliche Tests geschrieben, wenn jemand interessiert ist ... hier ist meine Version>
quelle
Ich bin gerade auf diese Frage gestoßen und habe eine andere Lösung zu bieten:
Die Idee hier ist, dass Sie innerhalb der Falte darauf warten, dass das nächste Element in der Liste abgeschlossen ist (unter Verwendung der For-Understanding-Syntax), und wenn das nächste fehlschlägt, greifen Sie einfach auf das zurück, was Sie bereits haben.
quelle
Sie können zukünftige Ergebnisse einfach mit Option umschließen und dann die Liste reduzieren:
quelle
Sie können auch erfolgreiche und erfolglose Ergebnisse in verschiedenen Listen sammeln:
quelle