È possibile utilizzare un for comprehension. Nell'esempio:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
object Stuff extends App {
val result = for {
f1 <- Future { 10 + 1 }
f2 <- Future { f1 + 2 }
} yield f2
result.onComplete(println)
}
Dove risultato sarà 13.
Qualsiasi classe che implementa una funzione propria map
e flatMap
può essere usato in questo modo in un for
.
Se non ti dispiace un'altra dipendenza, si può anche usare una libreria come scalaz ed esplicitamente usare monadica vincolante per appiattire le cose (EDIT codificato alcuni tipi di opzioni per affrontare un commento qui sotto):
import scalaz._
import Scalaz._
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.util.{Success,Failure}
object BindEx extends App {
def f1(i: String): Future[Int] = Future { i.length }
def f2(i: Int): Future[Option[Double]] = Future { Some(i/Math.PI) }
def f3(i: Option[Double]): Future[Option[Double]] = Future {
i match {
case Some(v) => Some(Math.round(v))
case _ => None
}
}
val result =
Monad[Future].point("Starting Point") >>=
f1 >>=
f2 >>=
f3
result.onComplete { x =>
x match {
case Success(value) => println("Success " + value)
case Failure(ex) => println(ex)
}
}
Await.result(result, 1 seconds)
}
e, infine, se avete appena operazioni parallele che si desidera legare dopo tutto sono riusciti che sono indipendenti, è possibile utilizzare scalaz builder applicativa:
val result = (
Future { 10 + 10 } |@|
Future { 20 - 3 } |@|
Future { Math.PI * 15 }
) { _ + _/_}
println(Await.result(result, 1 seconds))
Questo vi permetterà di tutti e 3 i futures completa, quindi applicare blocco a 3 argomenti.
fonte
2015-02-05 12:54:00
se si avvicinò con un esempio che compila in realtà quando si incolla in un IDE, potrebbe essere più facile per suggerire miglioramenti ... –
@KimStebel appena cambiato il codice di quindi è più universale –
Si dovrebbe evitare di impilare 'Future' in primo luogo, usando' Future.traverse' o 'Future.sequence'. – Dimitri