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