2016-12-30 4 views
0

Ich bemerkte einige interessante Verhalten über Karte, flatMap und Zukunft, aber ich bin nicht in der Lage zu verstehen, was dieses VerhaltenInteressante Karte und flatMap Beobachtungen - Future, Scala

//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) 
} 

Ergebnis

future2 
future1 
future3 
result is 6 

verursacht Wenn ich den obigen Code zur Karte ändere, erhalte ich eine leere Liste(). Ich kann nicht verfolgen, woher diese leere Liste stammt.

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

Ergebnis

future3 
future2 
future1 
result is List() 

Wenn ich nur zwei zukünftige Objekte und Karte verwenden, bekomme ich Erfolg (3) und nicht eine leere Liste()

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

Ergebnis

future3 
future2 
future1 
result is Success(3) 
+1

Wenn Sie auf die neueste Version von Scala 2.11 oder direkt auf Scala 2.12.x aktualisieren, dann sehen Sie eine viel genauere Stringdarstellung als "List()" –

+0

Details zu dem, was Viktor sagt, sind https: // Probleme .scala-lang.org/browse/SI-9488. Beachten Sie, dass Scala 2.11.9 noch nicht veröffentlicht wurde, also gibt es noch keine offizielle Version 2.11 mit dem Update (die 2.11 Nightlies haben es). –

Antwort

2

Im ersten Fall ist der Ergebnistyp Future[Int], Im zweiten Fall ist das Ergebnis Rückgabetyp Future[Future[...]] (einige verschachtelte Zukunft)

Im ersten Fall, wenn Sie die onComplete tun, die

val result: Future[Int] = ??? 

result onComplete { println } 

Der obige Code Success(1)

In kehrt ist der zweite Fall

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

result onComplete { println } 

Diese unevaluierten Zukunft führen können, ist, warum Siesehen. Siehe den Scala repl-Ausgang unten. Schauen Sie sich den Ergebnistyp von 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) 

Anregung

den Unterschied zwischen flatMap Wissen und Karte und weiß, wann flatMap und Karte zu verwenden.