Estoy buscando una manera de convertir una lista de futuros de longitud arbitraria en una lista de futuros. Estoy usando Playframework, así que en última instancia, lo que realmente quiero es un Future[Result]
, pero para simplificar las cosas, digamos que la Future[List[Int]]
forma normal de hacer esto sería usar Future.sequence(...)
pero hay un giro ... La lista que me dan generalmente tiene alrededor de 10-20 futuros en él, y no es raro que uno de esos futuros falle (están realizando solicitudes de servicios web externos). En lugar de tener que volver a intentarlo todos en caso de que uno de ellos falle, me gustaría poder acceder a los que tuvieron éxito y devolverlos.
Por ejemplo, hacer lo siguiente no funciona
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
En lugar de obtener la única excepción, me gustaría poder sacar el 1 y el 3 de allí. Intenté usar Future.fold
, pero aparentemente solo llama Future.sequence
detrás de escena.
¡Gracias de antemano por la ayuda!
.recover
era de hecho la pieza que faltaba para mí._.collect{ case Success(x) => x}
lugar de_.filter(_.isSuccess)
deshacerse deTry
en tipo defutureListOfSuccesses
..recover(x => Failure(x))
no es válido, use.recover({case e => Failure(e)})
en su lugarScala 2.12 tiene una mejora
Future.transform
que se presta en una respuesta con menos códigos.fuente
Probé la respuesta de Kevin y encontré un problema técnico en mi versión de Scala (2.11.5) ... Lo corrigí y escribí algunas pruebas adicionales si alguien está interesado ... aquí está mi versión>
fuente
Acabo de encontrarme con esta pregunta y tengo otra solución que ofrecer:
La idea aquí es que dentro del pliegue está esperando que se complete el siguiente elemento de la lista (usando la sintaxis de comprensión) y si el siguiente falla, simplemente recurra a lo que ya tiene.
fuente
Puede envolver fácilmente el resultado futuro con la opción y luego aplanar la lista:
fuente
También puede recopilar resultados exitosos y no exitosos en diferentes listas:
fuente