2016-12-30 44 views
0

我注意到了有關的地圖,flatMap和未來幾個有趣的行爲,但我無法理解是什麼原因造成這種現象有趣的地圖和flatMap觀察 - 未來,斯卡拉

//I have 3 Future objects. 

object ConcurrencyExample extends App { 

    val time = System.currentTimeMillis() 


val future1 = Future{println("future1");1} 
    val future2 = Future{println("future2");2} 
    val future3 = Future{println("future3");3} 

//I want to add 1,2 and 3. I can do it using flatMap 

val result = future1 flatMap (f1=> future2.flatMap(f2 => future3.map(f3=> f3+f2+f1))) 

result onComplete{ 
    case Success(v)=>println("result is "+v) 
    case Failure(e) =>println("failed result:"+e) 
    } 


    Thread.sleep(1000) 
} 

結果

future2 
future1 
future3 
result is 6 

如果我將上面的代碼更改爲map,我會得到一個空的List()。我無法跟蹤這個空列表來自哪裏?

val result = future1 map (f1=> future2.map(f2 => future3.map(f3=> f3+f2+f1))) 

結果

future3 
future2 
future1 
result is List() 

如果我只用兩個未來的對象和地圖,我獲得成功(3),而不是一個空列表()

val result = future1 map (f1=> future2.map(f2 => f2+f1)) 

結果

future3 
future2 
future1 
result is Success(3) 
+1

如果您升級到最新版本的Scala 2.11或直接升級到Scala 2.12.x,那麼您會看到比「List()」多的字符串表示形式 –

+0

有關Viktor在https://問題上的說明的詳細信息.scala-lang.org /瀏覽/ SI-9488。請注意,Scala 2.11.9還沒有發佈,所以目前還沒有正式的2.11版本(2.11 nightlies有)。 –

回答

2

在第一種情況下,結果返回類型是Future[Int],在第二種情況下,結果返回類型爲Future[Future[...]](一些嵌套未來)

在第一種情況下,當你做的onComplete是

val result: Future[Int] = ??? 

result onComplete { println } 

上面的代碼將返回Success(1)

在第二種情況

val result: Future[Future[..]] = ??? 

result onComplete { println } 

這可能會導致不計算未來,這就是爲什麼你看到List()。請參閱下面的Scala repl輸出。看看結果類型Future { Thread.sleep(1000); 1 }

scala> import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.ExecutionContext.Implicits.global 

scala> val f = Future { Thread.sleep(1000); 1 } 
f: scala.concurrent.Future[Unit] = List() 

scala> f onComplete { println } 
Success(1) 

建議

知道flatMap之間的差異,地圖和知道什麼時候使用flatMap和地圖。