2016-04-23 43 views
8

Mi chiedo la differenza tra onComplete e foreach quando usiamo un Future in Scala.Qual è la differenza tra onComplete e foreach per un futuro in Scala?

f onComplete (_ => doSomething(_))

e

f foreach (_ => doSomething(_))

  1. fare le linee sopra di piombo codice per lo stesso risultato?

  2. Se voglio eseguire Qualcosa con Future f solo dopo che è stato completato. Cosa dovrei fare? Dovrei usare IsCompleted come questo:

    if(f.isCompleted) f onComplete (_ => doSomething(_))

voi ragazzi Grazie molto

risposta

13

La differenza principale è il callback onComplete viene chiamato anche se il futuro completa con un fallimento, mentre foreach (e onSuccess) le funzioni vengono chiamate solo in caso di risultato riuscito.

In realtà, il parametro onComplete s' è una funzione Try[T] => U: la funzione si passa sarà chiamato con un Success[T] come argomento se il futuro è successo o con un Failure se c'era un'eccezione:

val f = Future { ??? } // this future completes with a failure 

// foreach only calls the callback if the future is successful 
f.foreach(_ => thisWillNeverExecute()) 

// This will print "future failed" after the future completes 
f.onComplete { 
    case Success(_) => println("future completed successfully") 
    case Failure(e) => println("future failed") 
} 

Inoltre, non è necessario controllare nulla per chiamare i metodi citati: onComplete/onSuccess/onFailure/foreach tutti pianificano una richiamata chiamata nell'implicito ExecutionContext in ambito, solo quando il futuro viene completato.

È possibile chiamarli anche se isCompleted è falso, verranno eseguiti solo quando il completamento del processo è riuscito o meno, a seconda di quale si è scelto.

Diamo un'occhiata al loro firme:

def onComplete[U](@f: Try[T] => U)(implicit executor: ExecutionContext): Unit 
  • onComplete prende una funzione Try[T] => U: questa funzione sarà eseguita sul implicit executor quando il futuro completata. L'argomento o sarà un Success[T] se il futuro è successo o un parametro Failure se il futuro è fallito

def onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit 
  • onFailure è un PartialFunction che viene eseguito solo sul implicit executor se il futuro non riesce con un Throwable per il quale è definito pf. Fondamentalmente è come chiamare la corrispondenza Completa solo alcuni Failure s, e infatti questo è esattamente il modo in cui è implementato nella libreria standard.

def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit 
  • onSuccess parametro è, simmetricamente a onFailure, un PartialFunction che viene eseguito solo sul implicit executor se il futuro completa con successo e la dotazione PartialFunction è definito per il valore.

def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit 
  • foreach è fondamentalmente la stessa onSuccess ma richiede una funzione totale. Ciò significa che f viene sempre eseguito se il futuro completa con successo

NB .: 'onSuccess' e 'onFailure' stanno per essere deprecato a 2.12. Vi suggerisco di leggere this series of posts by Viktor Klang per scoprire come sarete interessati dalle modifiche

+0

Grazie, la vostra risposta è molto dettagliata. Ho imparato molto da questo. Quindi, significa che 'foreach' è equivalente a' onSuccess'. È giusto? – hminle

+1

'foreach' è una versione" totale "di' onSuccess'. se si passa una funzione totale a 'onSuccess' sono virtualmente equivalenti. Sia 'foreach' che' onSuccess' sono implementati in termini di 'onComplete', ma cambierà in 2.12 –

+0

Grazie :), l'ho capito – hminle