[英]Chaining Futures in Scala
Consider this:考虑一下:
val f1 = Future {}
val f2 = Future {}
f1.flatMap(_ => f2)
In this case, is it possible that f2
completes before f1
completes ?在这种情况下,
f2
是否可能在f1
完成之前完成?
I suspect yes.我怀疑是的。
So how could I fix that ?那么我该如何解决呢? I mean, how can I make sure that
f2
starts only after f1
has completed ?我的意思是,如何确保
f2
仅在f1
完成后启动?
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.一旦您定义了
Future {}
它就会立即启动,这意味着当您将 f1 和 f2 定义为两个期货 f1 开始执行然后 f2 以正确方式启动时。
So any of those can finish first.因此,其中任何一个都可以先完成。
See REPL example below when you define Future
as val
it is executed right away.当您将
Future
定义为val
时,请参阅下面的 REPL 示例,它会立即执行。
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, .您可以使用理解来确保 f1 首先启动, 。 for comprehension itself is expanded to
flatMap
for comprehension 本身被扩展为
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.或者甚至在您的示例中,您可以使用内联 Futures 而不是评估变量。
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 替换 val,基本上是即时计算到惰性计算。
def f1 = Future {}
def f2 = Future {}
f1.flatMap(_ => f2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.