Consider this:
val f1 = Future {}
val f2 = Future {}
f1.flatMap(_ => f2)
In this case, is it possible that f2
completes before f1
completes ?
I suspect yes.
So how could I fix that ? I mean, how can I make sure that f2
starts only after f1
has completed ?
Would this work/(be good style):
def f1 = Future {}
def f2 = Future {}
f1.flatMap(_ => f2)
?
As soon as you define a Future {}
it is started right away, which means when you define f1 and f2 as two futures f1 starts executing and then f2 starts right way.
So any of those can finish first.
See REPL example below when you define Future
as val
it is executed right away.
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> val f1 = Future { Thread.sleep(5000); println("f1 finished")}
f1: scala.concurrent.Future[Unit] = Future(<not completed>)
scala> val f2 = Future { println("f2 finished")}
f2 finished
f2: scala.concurrent.Future[Unit] = Future(<not completed>)
scala> f1 finished
you can use for comprehension to make sure f1 starts first, . for comprehension itself is expanded to flatMap
scala> for { f1 <- Future { Thread.sleep(5000); println("f1 started"); 100}
| f2 <- Future { println("f2 started"); 200 }
| } yield (f1, f2)
res1: scala.concurrent.Future[(Int, Int)] = Future(<not completed>)
scala> f1 started
f2 started
Or even within your example, you can use inline Futures instead of evaluated variables.
scala> Future { Thread.sleep(5000); println("f1 finished")}.flatMap {f => Future {println("f2 started"); 200}}
res2: scala.concurrent.Future[Int] = Future(<not completed>)
scala> f1 finished
f2 started
And the best way is to use functions,
scala> def f1 = Future { Thread.sleep(5000); println("f1 finished")}
f1: scala.concurrent.Future[Unit]
scala> def f2 = Future {println("f2 started"); 200}
f2: scala.concurrent.Future[Int]
scala> f1.flatMap(_ => f2)
res3: scala.concurrent.Future[Int] = Future(<not completed>)
scala> f1 finished
f2 started
Replace val with def, basically instant compute to lazy compute.
def f1 = Future {}
def f2 = Future {}
f1.flatMap(_ => f2)
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.