2014-04-20 89 views
0

我有以下Scala代碼,使用Scala 2.10爲什麼Scala Future會使用flatMap返回None並理解?

package reactive 

import scala.concurrent.future 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.Future 

object futuresum extends App { 

    def f1 = future { 12 } 
    def f2 = future { 13 } 

    val result1 = f1.flatMap(x => f2.map(y => x + y)) 
    println(result1.value) 

    val result2 = for (x <- f1; y <- f2) yield (x + y) 
    println(result2.value) 

} 

該代碼使用應打印25,但它打印None

None 
None 

什麼是錯的代碼?

編輯

現在,這對我的作品:

package reactive 

import scala.concurrent.future 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.Future 
import scala.concurrent.Await 
import scala.concurrent.duration.Duration 

object futuresum extends App { 

    def f1 = future { 12 } 
    def f2 = future { 13 } 

    val result1 = f1.flatMap(x => f2.map(y => x + y)) 
    result1.onComplete(b => println(b)) 

    val result2 = for (x <- f1; y <- f2) yield (x + y) 
    result2.onComplete(b => println(b)) 

    Await.result(result1, Duration.Inf) 
    Await.result(result2, Duration.Inf) 
} 

回答

2

https://stackoverflow.com/a/16358119/3328933

「期貨是在一個專門的線程池執行我會偷雷吉斯讓 - 吉爾出色答卷。如果你的主程序不等待將來,它會立即退出,將來也沒有機會執行。你可以在這裏做的是在你的主程序中使用Await來阻止m艾因線程,直到將來執行:」

package reactive 

import scala.concurrent.Await 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.future 
import scala.concurrent.duration._ 

object futuresum extends App { 

    def f1 = future { 12 } 
    def f2 = future { 13 } 

    val result1 = f1.flatMap(x => f2.map(y => x + y)) 
    result1 onSuccess { case res => println(res) } 
    Await.result(result1, 2 seconds) 

    val result2 = for (x <- f1; y <- f2) yield (x + y) 
    result2 onSuccess { case res => println(res) } 
    Await.result(result2, 2 seconds) 
} 
3

我的猜測是,之間的‘結果’S及其println期貨還沒有足夠的時間來產卵/發送到自己的線程。檢查這個快速REPL會話:

scala> f1.flatMap(x => f2.map(y => x + y)).value 
res2: Option[scala.util.Try[Int]] = None 

scala> f1.flatMap(x => f2.map(y => x + y)) 
res3: scala.concurrent.Future[Int] = [email protected] 

scala> res3.value 
res4: Option[scala.util.Try[Int]] = Some(Success(25)) 

讓我們嘗試不同的東西:

scala> f1.flatMap(x => f2.map(y => x + y)).onComplete(println(_)) 

scala> Success(25) // Press enter here. onComplete mixed with REPL output. 

闖闖:

scala> val later=f1.flatMap(x => f2.map(y => x + y)); later.onComplete(println(_)); println(later.value); 
None 
later: scala.concurrent.Future[Int] = scala.concurrent.impl[email protected] 
Success(25) 

現在這是一個令人困惑的輸出。這是我的觀點的一個很好的例子,雖然:

  1. 首先,創建later其中包含的計算,這將是一段時間以後執行 。
  2. 將此計算綁定到一個將在完成時觸發的事件。
  3. 打印可能未完成計算的結果。

現在思考兩行執行。 1,2和3發生在第一個執行主線或主線程中。未來內部,{ 12 },map,flatMat發生在另一行執行。

1

使用Await.result(result,duration)或Thread.sleep等待將來的線程完成。 然後您可以檢查future.isComplete以確保未來完成。

Await.result(result2, 3 seconds) 
if(result2.isCompleted) 
println(result2.value) 
相關問題