2015-09-01 8 views
11

Wie kann ich onComplete in Scala Struktur auf diese Weise handeln:Scala Rückgabewert von onComplete

Abb 1

{ 
    var x; 
    if(result.isFailure){ 
    x = foo() // foo is a future 
    } 

    if(result.isSuccess){ 
    x = 5 
    } 
    bar(x) 
} 

Ich dachte, ich es auf diese Weise tun könnte.

Abb. 2

var x = foo onComplete { 
    case Success(x) => 5 
    case Failure(t) => foo() //foo is a future 
} 
bar(x) 

Aber onComplete, onFailure und onSuccess alle haben Unit als ihre Rückgabetyp,

onComplete[U](f: (Try[T]) ⇒ U)(implicit executor: ExecutionContext): Unit 
onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit 
onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit 

Wie kann ich etwas erreichen, Figur zwei-ish ohne eine Var zu verwenden?

+0

Was ist "foo"? Eine 'Zukunft'? Ich denke, du solltest dein Beispiel ein wenig konkretisieren. – mattinbits

+0

@mattinbits, danke, bearbeitet die Frage. – krzasteka

Antwort

6

Es wird davon abgeraten, den aktuellen Thread zu blockieren, indem ein Ergebnis aus einer Zukunft erwartet wird. Stattdessen sollten Sie die Funktion bar() aufrufen, um die Ergebnisse der result Zukunft zu verarbeiten.

result map {r => 
    5 
} recover { 
    case _ => foo() 
} map {r => 
    bar(r) 
} 
+0

Stellt nur Fänge nicht wieder her. Ausnahmen? Könnte ein Fehler ohne Ausnahme auftreten? Fragt nur aus Neugier. – mfirry

+1

Zukunft kann nur mit einer Ausnahme fehlschlagen. Entweder kann es geworfen werden und nicht in den Körper einer Zukunft eingefangen werden, oder, zum Beispiel, ein Versprechen, das thad Zukunft geschaffen hat, wurde mit der Methode 'failure' abgeschlossen, die mit Throwable parametrisiert wurde. –

+0

Ehrfürchtig. Danke @alexander – mfirry

4

Sie können Ihr Ziel mit

val x: Future[Int] = foo.map(x => 5).recover{case f => foo()} 
// do some more work with your future 
x.map(bar(_)) 

Unter der Annahme, dass foo: Future[_] und foo(): Int erreichen.

+0

können Sie darüber nachdenken, wie Sie es ohne ein 'Await' machen können, um nicht zu blockieren? – krzasteka

+1

@krzasteka, ich habe hier nur'Await' verwendet, um zu visualisieren, dass Sie an einem Punkt Ihrer Berechnung, wenn Sie das Ergebnis Ihrer 'Zukunft' abrufen wollen, darauf warten müssen. Aber es ist richtig, dass Sie weitere Operationen an das zukünftige 'x' ketten können. –