[英]Chaining Futures in Scala
考虑一下:
val f1 = Future {}
val f2 = Future {}
f1.flatMap(_ => f2)
在这种情况下, f2
是否可能在f1
完成之前完成?
我怀疑是的。
那么我该如何解决呢? 我的意思是,如何确保f2
仅在f1
完成后启动?
这行得通吗/(风格很好):
def f1 = Future {}
def f2 = Future {}
f1.flatMap(_ => f2)
?
一旦您定义了Future {}
它就会立即启动,这意味着当您将 f1 和 f2 定义为两个期货 f1 开始执行然后 f2 以正确方式启动时。
因此,其中任何一个都可以先完成。
当您将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
您可以使用理解来确保 f1 首先启动, 。 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
或者甚至在您的示例中,您可以使用内联 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
最好的方法是使用函数,
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
用 def 替换 val,基本上是即时计算到惰性计算。
def f1 = Future {}
def f2 = Future {}
f1.flatMap(_ => f2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.