I've been trying to simplify the way I do futures in Scala. I got at one point a Future[Option[Future[Option[Boolean]]
but I've simplified it further below. Is there a better way to simplify this?
Passing a future of "failed" doesn't seem like the best way to do this. i.e. in the sequential world I simply returned "FAIL!!" any time it failed rather than continuing to the end. Are there other ways?
val doSimpleWork = Future {
//Do any arbitrary work (can be a different function)
true //or false
}
val doComplexWork = Future {
//Do any arbitrary work (can be a different function)
Some("result") //or false
}
val failed = Future {
//Do no work at all!!! Just return
false
}
val fut1 = doSimpleWork
val fut2 = doSimpleWork
val fut3 = (fut1 zip fut2).map({
case (true, true) => true
case _ => false
})
val fut4 = fut3.flatMap({
case true =>
doComplexWork.flatMap({
case Some("result") =>
doSimpleWork
case None =>
failed
})
case false =>
failed
})
fut4.map({
case true =>
"SUCCESS!!!"
case _ =>
"FAIL!!"
})
Note that in your example, because you're eagerly instantiating the Futures
to a val
, all of them will start executing as soon as you declare them (val x = Future {...}
). Using methods instead will make the Futures execute only when they're requested by the chain of execution.
One way to avoid the further computation would be to throw an exception, then handle it with onFailure
:
def one = future { println("one") ; Some(1) }
def two = future { println("two") ; throw new Exception("no!"); 2 }
def three = future { println("three") ; 3 }
val f = one flatMap {
result1 => two flatMap {
result2 => three
}
}
f onFailure {
case e: Exception =>
println("failed somewhere in the chain")
}
You can see here that "three" isn't supposed to be printed out, because we fail on two
. This is the case:
one
two
failed somewhere in the chain
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With