2014-09-20 9 views
9

Biorąc pod uwagę ten kodCo jest wykorzystanie Scala Future.fallbackTo

val f1: Future[Int] = Future { 5 } //Future.failed(new Exception("sorry")) 
val f2: Future[Int] = Future { 6 } 

val result : Future[Int] = f1.fallbackTo { 
    println("Fall back to that F") 
    f2 
} 

wynik zawiera wynik f1. Jednak kod w bloku fallbackTo jest wykonywany niezależnie od tego, czy f1 ulegnie awarii, czy nie. Spodziewałem się, że funkcja fallbackTo będzie wykonana tylko w przypadku niepowodzenia f1.

Być może mój przykład jest zbyt prosty (lub po prostu zły), ale jaki jest pożytek z fallbackTo?

+0

To wydaje się być związane z problemem: https: //issues.scala-lang. org/browse/SI-6913 –

Odpowiedz

19

masz rację, f1 jest zwracany, jeśli jest to sukces, jeśli nie f2, druk widzisz to ze względu na fakt, że blok nie jest uwzględniany leniwie:

def fallbackTo[U >: T](that: Future[U]): Future[U] 

więc wydaje się, że f2 jest rozpoczęty, gdy zostanie przekazany do fallbackTo (i stąd zostanie wykonana instrukcja print). Prawdopodobnie jest to wybór projektu, gdyby został leniwie oceniony f2 zostałby uruchomiony dopiero po awarii od f1.

Jeśli chcesz uniknąć tego rodzaju zachowania można użyć recoverWith który jest zwolniony dopiero po awarii:

f1.recoverWith{ case _ => println(123); Future { 6 } } 
+2

W tym przypadku f2 jest uruchamiany równolegle z f1. Aby rozwiązać ten problem, Przyszłość powinna być zdefiniowana wewnątrz odzyskiwania/odzyskiwania z treścią, lub być defem zamiast wartością val – roterl

+0

@roterl dzięki, masz rację, kontrakty futures są uruchamiane natychmiast po ich zadeklarowaniu. –