2016-04-20 10 views
0

Könnten Sie mir bitte es in einer besseren Art und Weise schreiben helfen:Scala Loswerden von verschachtelten Futures

Future { 
    Thread sleep 200 
    5 
} onComplete{ 
    case Success(e) => Future { 
     doSomething(e) 
     Thread sleep 200 
     6 
    } onComplete { 
     case Success(e) => 
      Future { 
       doSomething(e) 
       Thread sleep 200 
      } onComplete { 
       case Success(_) => println("finished") 
       case Failure(e) => e.printStackTrace() 
      } 
     case Failure(e) => e.printStackTrace() 
    } 

    case Failure(e) => e.printStackTrace() 
} 

Jetzt ist der Code sieht schlecht aus, und wenn ich mehr Futures auf diese Weise hinzugefügt würde es noch schlimmer geworden ... Dies ist offensichtlich ein Beispiel, um das Problem zu zeigen, daher würde ich es begrüßen, einen größeren Zusammenhang zu erwähnen.

@update Wenn es nicht klar genug ist, werde ich versuchen, zu klären. Ich habe drei Futures und möchte das erste ausführen, wenn es fertig ist, führe das zweite aus, wenn es fertig ist - das dritte. Die zweite Zukunft verwendet das Ergebnis der ersten und die dritte verwendet das Ergebnis der zweiten. Wenn einer der Futures fehlschlägt, wird die Stapelverfolgung gedruckt und die Ruffolge bricht ab. Dies ist, was ich im obigen Code zeigen wollte, und ich möchte es, wenn möglich, auf bessere, nicht verschachtelte Weise erreichen.

@update 2 Es wäre auch toll, wenn ich Ausfall jeder Zukunft separat

+0

Es ist nicht klar, was Sie erreichen möchten – mfirry

+0

ok, ich aktualisierte die Frage –

Antwort

3

ähnlich wie Sammlungen behandeln würde können Sie map() und flatMap() Futures (scaladoc), um sie zu kombinieren:

Future { 
    Thread sleep 200 
    5 
}.map { result => 
    doSomething(result) 
    Thread sleep 200 
    6 
}.map { result => 
    doSomething(result) 
    Thread sleep 200 
}.onComplete { 
    case Success(_) => 
    // All steps completed successfully 
    println("finished") 
    case Failure(e) => 
    // This can be a failure from any of the steps 
    e.printStackTrace() 
} 

map erzeugt ein Ergebnis, während flatMap eine Future-Instanz generiert.

Alternativ können Sie for-comprehensions verwenden, die nur syntaktischer Zucker für (flache) Kartenaufrufe sind.

+0

danke, aber kann ich Ausfall jedes Future separat mit diesem Ansatz behandeln? –

+0

Sie können überprüfen, welche Art von Throwable Sie erhalten, aber Sie können nicht sagen, welcher Schritt genau verursacht hat (es sei denn, jeder Schritt wirft einen eindeutigen Typ von Throwable natürlich). [Die akzeptierte Antwort in diesem Thread erklärt es gut] (http://stackoverflow.com/questions/27945014/failure-in-scala-futures-for-comprehension). – alextsc