2015-06-05 9 views
10

Il significato andThen che ho appreso da questo answer è un compositore di funzioni.Perché il eThen of Future non concatena il risultato?

dire che

f andThen g andThen h 

sarà pari a

h(g(f(x))) 

Ciò implica la h function riceveranno input da g(f(x))

Ma per la andThen in Future, tutta la chiusura della seguente andthen riceve sempre il risultato dell'originale Future.

Future{ 
    1 
}.andThen{ case Success(x) => 
    println(x) // print 1 
    Thread.sleep(2000) 
    x * 2 
}.andThen{ case Success(x) => 
    println(x) // print 1 
    Thread.sleep(2000) 
    x * 2 
} 

confronta con

val func: Function1[Int, Int] = { x: Int => 
    x 
}.andThen { y => 
    println(y) // print 1 
    y * 2 
}.andThen { z => 
    println(z) // print 2 
    z * 2 
} 
func(1) 

Qual è la ragione per fare Future :: andthen (s) ricevono tutte lo stesso risultato da Future originale invece di concatenamento futuro? Ho osservato che questi concatenati e Allora saranno eseguiti sequenzialmente, quindi la ragione potrebbe non essere per scopi paralleli.

risposta

14

scala.concurrent.Future è realizzata come compromesso di due approcci asincroni:

  1. orientata agli oggetti observer che consente legame di gestori asincroni
  2. funzionale monad che offre ricche funzionalità di composizione funzionali.

lettura Future.andThen's docs:

applica la funzione side-effettuando al risultato di questo futuro, e restituisce un nuovo futuro con il risultato di questo futuro.

Quindi andThen è probabilmente l'universo OOP. Per ottenere simile risultato simile a Function1.andThen si potrebbe utilizzare map metodo:

Future(1).map {_ * 2}.map {_ * 2} 

andThen differisce da onComplete con una piccola cosa: con conseguente futuro della andThen ancora tornare stesso risultato, ma dovrà attendere fino osservatore fornito tornerà o gettare qualcosa. È per questo che c'è scritto nei documenti:

Questo metodo permette di far rispettare che i callback vengono eseguiti in un ordine specifico .

noti inoltre terza riga da documenti:

noti che se uno dei callback andthen concatenati genera un'eccezione, tale eccezione non viene propagata alle successive callback andthen. Al contrario, le richiamate successive eThen hanno il valore originale di questo futuro.

Quindi è 'completamente non fare nulla con le nuove Future' risultato s. Non potrei nemmeno rovinarlo con la sua propria eccezione. Questo andThen e onComplete solo sequenziale e associazione parallela di osservatori.

+1

Posso dire che è un'altra versione di onComplete ma restituire "this" in modo che possa associare più gestori di callback "observer" nello stile concatenamento? –

+0

@ChenOT Sì. Praticamente – Odomontois

+0

@ Ma con una differenza. Aggiungerò questo a asnwer – Odomontois