The objective of the code below is to execute Future f3
or f4
depending on a condition. Note that the condition depends on the result of Future f1
or f2
, so it has to wait. This seems to work, however since f1
and f2
are futures this code shouldn't run sequentially. Is this code correct?
object TestFutures extends App {
val f1 = Future { 1 }
val f2 = Future { 2 }
val f3 = Future { 3 }
val f4 = Future { 4 }
val y = 1
for {
condition <- if (y>0) f1 else f2
_ <- if (condition==1) f3.map {a => println("333")} else f4.map {b => println("444")}
} yield ()
Thread.sleep(5000)
}
No it is not correct. When you create a Future
like you do it, it starts the computations immediately. Before reaching for
comprehension, all of your 4 futures are running already. You need to create them later, depending on the conditions.
val y = 1
for {
condition <- if (y > 0) Future { 1 } else Future { 2 }
_ <- if (condition == 1)
Future { 3 }.map(a => println("333"))
else
Future { 4 }.map(b => println("444"))
} yield ()
It is probably good to extract creating each of those to a method, that you will just call, for sake of readability.
It should be obvious they start running when they are created because you can just say
Future(1).map(x => println(x))
and it works without any sort of triggering. Anyway try to run the following code
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def printWhenCompleted[A](f: Future[A]): Future[A] = f.map { x =>
println(x)
x
}
val f1 = printWhenCompleted(Future { 1 })
val f2 = printWhenCompleted(Future { 2 })
val f3 = printWhenCompleted(Future { 3 })
for {
r3 <- f3
r2 <- f2
r1 <- f1
} yield r1 + r2 + r3
it should give you those numbers in random order, instead of sequential 3, 2, 1
Here is implementation of the first code (without println
) using flatMap
val futureCondition = if (y > 0) Future(1) else Future(2)
futureCondition.flatMap(condition => if (condition == 1) Future(3) else Future(4))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.