繁体   English   中英

在 Scala 中链接 Futures

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM