You can use for understanding . In the example:
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) }
If the result is 13.
Any class that implements the correct map and flatMap functions can be used this way in for .
If you don't mind another dependency, you can also use a library such as scalaz, and explicitly use monadic binding to align things (EDIT encoded some types of options to respond to the comment below):
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) }
And finally, if you only have parallel operations that you want to bind, after all of them were independent, you can use the scalaz applicative builder:
val result = ( Future { 10 + 10 } |@| Future { 20 - 3 } |@| Future { Math.PI * 15 } ) { _ + _ / _} println(Await.result(result, 1 seconds))
This will complete all 3 futures, and then apply the block to 3 arguments.
Rich henry
source share