2015-09-01 15 views
11

Come posso strutturare onComplete a Scala di agire in questo modo:Scala valore restituito da onComplete

Fig 1

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

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

ho pensato che avrei potuto fare in questo modo:.

Fig. 2

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

Ma onComplete, onFailure e onSuccess tutti hanno Unit come loro tipo di ritorno,

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 

Come posso ottenere qualcosa di figura in due senza utilizzare una var?

+0

Che cos'è 'foo'? Un 'futuro'? Penso che dovresti dare un po 'di spessore al tuo esempio. – mattinbits

+0

@mattinbits, grazie, modificato la domanda. – krzasteka

risposta

6

Si sconsiglia di bloccare il thread corrente in attesa di un risultato da un futuro. Invece, dovresti chiamare la funzione bar() sull'elaborazione dei risultati del futuro result.

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

Non recupera solo catture Eccezioni? Potrebbe esserci un fallimento senza un'eccezione? Basta chiedere per curiosità qui. – mfirry

+1

Future può essere fallito solo con un'eccezione. O può essere gettato e non catturato all'interno del corpo di un futuro, o, per esempio, una promessa che ha creato il futuro è stata completata con il metodo 'failure', che è stato parametrizzato con Throwable. –

+0

Fantastico. Grazie a @alexander – mfirry

4

È possibile raggiungere il tuo obiettivo con

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

Supponendo che foo: Future[_] e foo(): Int.

+0

puoi pensare a come farlo senza un 'Await' per non bloccare? – krzasteka

+1

@krzasteka, ho usato solo "Await" qui per visualizzare quello ad un certo punto del tuo calcolo quando vuoi recuperare il risultato del tuo "Futuro" che devi aspettare. Ma è giusto che puoi concatenare ulteriori operazioni al futuro 'x'. –