Some ideas I gathered from various places for working with Futures in for comprehensions.
Import what we need for all the examples.
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
Saw something similar to this on SO or somewhere. The question was around what is an idiomatic way to handle Futures and filters (Ifs) on (the results of those Futures) inside of a for comprehension ie. we want to check the results of a Future and depending on it's result we may either want to construct another Future task or return some exception.
Here is a predicate
function that either returns a Future[Unit]
or a Future wrapping a provided exception.
def predicate(condition: Future => Boolean)(fail: Exception): Future[Unit] =
if (condition) Future( () ) // create a Future[Unit]
else Future.failed(fail) // or returns a Future containing the provided Exception
The following tests the value of the first Future and if the
val result = for {
x <- Future(1)
y <- predicate(x == 2)(new Exception("x not 2"))
} yield y
val result = for { x <- Future(2) y <- predicate(x == 2)(new Exception("x not 2")) } yield y
val result = for {
x <- Future(1)
y <- predicate(x == 2)(new Exception("x not 2"))
z <- Future(3) // Note: as an aside anything here will only run if the predicate is true
} yield y