簡體   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