簡體   English   中英

斯卡拉期貨的理解

[英]Scala Futures in For Comprehension

我想把頭放在Scala周圍,我想知道以下內容是什么:

val fFuture: Future[Int] = Future { println("f called"); 3 }                                                                                                                    
val gFuture: Future[Int] = Future { println("g called"); 4 }                                                                                                                    

for {
    f <- fFuture
    g <- gFuture
} yield f  

期貨是為了理解而執行的,對嗎? 那么f在yield語句中做什么? 這僅僅是意味着它可用嗎? 如果該return value在函數內部,是否將其視為return value

期貨在這里開始執行:

val fFuture: Future[Int] = Future { println("f called"); 3 }                                                                                                                    
val gFuture: Future[Int] = Future { println("g called"); 4 } 

因此,兩個執行都是並行開始的。 但是,如果您不小心將Future{...}放在了理解之內-它們將被順序執行。

基本理解基本上是預訂並將兩個結果合並為一個Future。 但是,在您的情況下,似乎第二個未來的結果被忽略了,這沒有意義。 有意義的代碼:

for {
    f <- fFuture
    g <- gFuture
} yield f + g

此代碼返回Future[Int] (與示例中的代碼相同)。 如果從該Future中提取價值,則得到3 + 4 = 7 但是,這仍然不是最佳方法,因為您的計算是獨立的,並且開發人員犯錯的可能性(如上所述)仍然很高,因此推薦的獨立計算方法是:

(fFuture zip gFuture) map {
  case (f, g) => f + g
}

這段代碼是透明的,這意味着即使您將Future{...}替換為fFuture Future{...} ,它的行為仍然相同(如果是Future它們將按原樣執行,但對於其他並發原語可能有所不同)

for-comprehension究竟在哪里有意義? 這里:

for {
    f <- Future{... 9}
    g <- if (f > 0) Future{...} else Future{...}
} yield g

由於g在這里取決於f無法並行運行它們,因此for提供了一種構成多個Future s的非阻塞方式。

對Scala Futures進行熱切評估,這意味着它們的值會立即在單獨的線程中計算。

當您運行取決於未來結果的操作時,當前線程將阻塞等待,直到被評估。 如果使用map或flatMap之類的組合器方法轉換Future,則將得到另一個代表最終結果的Future(運行這些操作的代碼無需阻塞)。

因此,在您的示例中,編譯器將for理解理解為以下表達式:

fFuture.flatMap(f => gFuture.map(g => f + g))

本身是在另一個線程中計算的Future [Int]。

在這種情況下,您不必使用理解,只需使用OnComplete。

ffuture.OnComplete {
Case Success(result) => println(s"$result')
Case Failure(ex) => ex.printStackTrace
}

如果您的未來依賴於其他未來,則需要理解:

var result =  for {
        f <- fFuture
        g <- f
    } yield g

在f完成之后,g future將得到解析,並且yield將會返回無論您返回的結果是什么。 在這種情況下,它將是Future [Int]。 有了yield,您可以做類似的事情。

yield g+f

要閱讀結果,您可以簡單地使用

result.onSuccess or onComplete

對於期貨,我發現這篇文章是最好的: http : //alvinalexander.com/scala/concurrency-with-scala-futures-tutorials-examples

我會說是的,這類似於函數中的返回值。 但這是用於理解語法的,不能與它一起使用return語句。 對於理解是寫map的更好方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM