await - Combinar secuencialmente un número arbitrario de futuros en Scala
await future scala (2)
andThen
es para los efectos secundarios. Le permite especificar algunas acciones para hacer después de que se complete el futuro y antes de que se use para otra cosa.
Usar mapa:
scala> List(1, 2, 3).foldLeft(Future { 0 }) {
| case (future, i) => future map { _ + i }
| } onSuccess { case x => println(x) }
6
Soy nuevo en scala e intento combinar varios futuros en scala 2.10RC3. Los Futures
deben ejecutarse en orden secuencial. En el documento Scala SIP14, el método y andThen
se define para ejecutar futuros en orden secuencial. Utilicé este método para combinar varios Futures
(ver ejemplo a continuación). Mi expectativa era que imprima 6
pero en realidad el resultado es 0
. ¿Qué estoy haciendo mal aquí? Tengo dos preguntas:
Primero, porque es el resultado 0
. En segundo lugar, ¿cómo puedo combinar varios Futures
, para que la ejecución del segundo Future
no comience antes de que se haya terminado el primer Future
?
val intList = List(1, 2, 3)
val sumOfIntFuture = intList.foldLeft(Future { 0 }) {
case (future, i) => future andThen {
case Success(result) => result + i
case Failure(e) => println(e)
}
}
sumOfIntFuture onSuccess { case x => println(x) }
Me gusta este enfoque genérico:
trait FutureImplicits {
class SeriallyPimp[T, V](futures: Seq[T]) {
def serially(f: T => Future[V])(implicit ec: ExecutionContext): Future[Seq[V]] = {
val buf = ListBuffer.empty[V]
buf.sizeHint(futures.size)
futures.foldLeft(Future.successful(buf)) { (previousFuture, next) =>
for {
previousResults <- previousFuture
nextResult <- f(next)
} yield previousResults += nextResult
}
}
}
implicit def toSeriallyPimp[T, V](xs: Seq[T]): SeriallyPimp[T, V] =
new SeriallyPimp(xs)
}
Luego mezcla el rasgo anterior y úsalo así:
val elems: Seq[Elem] = ???
val save: Elem => Future[Result] = ???
val f: Future[Seq[Result]] = elems serially save
Este código podría mejorarse para preservar el tipo de colección de entrada. Ver este artículo por ejemplo.