2015-01-27 14 views

risposta

41

Il consiglio che ho ricevuto dal forum Couchbase è quello di utilizzare osservabili nidificate:

Observable 
    .from(modifications) 
    .flatmap((data1) -> { 
     return op1(data1) 
      ... 
      .flatmap((data2) -> { 
       // I can access data1 here 
       return op2(data2); 
      }) 
    }); 

EDIT: Ho lo segnaliamo come la risposta accettata come sembra essere il più consigliato. Se l'elaborazione è troppo complessa per nidificare tutto, è anche possibile controllare la soluzione con le chiamate di funzione.

+0

Questo è quello che mi ritrovo a fare spesso e ha funzionato fino ad ora. – Will

3

Una possibilità sarebbe quella di utilizzare una chiamata di funzione:

private static Observable<T> myFunc(final Object data1) { 
    return op1(data1) 
     ... 
     .flatmap((data2) -> { 
      // I can access data1 here 
      return op2(data2); 
     }); 
} 

Observable 
    .from(modifications) 
    .flatmap((data1) -> { return myFunc(data1); }) 

MA: correggetemi se sbaglio, ma non si sente come il modo reattivo-programmazione di farlo

+2

è questo molto diverso da quello del prima opzione? – Will

+0

@Solo sì, suppongo che sia funzionalmente simile all'utilizzo di chiamate annidate. Per l'elaborazione complessa probabilmente non è una cattiva scelta dopo tutto. –

10

altro possibilità è quella di mappare il risultato di op1 a un org.apache.commons.lang3.tuple.Pair che contiene la variabile e passare che lungo:

Observable 
    .from(modifications) 
    .flatmap((data1) -> { 
     return op1(data1).map(obj -> { return Pair.of(data1,obj); }); 
    }) 
    ... 
    .flatmap((dataPair) -> { 
     // data1 is dataPair.getLeft() 
     return op2(dataPair.getRight()); 
    }) 

funziona ma ci si sente un po 'uncomfortabl e per avere variabili nascoste all'interno di una coppia/triplo/... e diventa molto prolisso se si utilizza la notazione Java 6.

Mi chiedo se esiste una soluzione migliore, forse un operatore RxJava potrebbe essere d'aiuto?

+2

Non penso che ci sia qualcosa di sbagliato in questo, ma ogni volta che sento di dover raggiungere la classe Pair, sento anche che sto facendo qualcosa di sbagliato. Il numero di volte in cui l'ho usato e poi rielaborato più tardi una volta che avrò una migliore comprensione sul mio dominio. – Will

+0

Questa è la soluzione che mi è venuta, anche se avrebbe creato un sacco di spazzatura rendendo le istanze 'Pair' solo per mantenere' data1' vicino a 'obj'. Mi chiedo se un 'combine 'funzionerebbe. – scorpiodawg

0

soluzione su questo thread funziona, ma per catene complesse rende il codice difficile da leggere, ho dovuto passare più valori e quello che ho fatto è stato creare una classe privata con tutti i parametri, trovo il codice più leggibile in questo modo,

private class CommonData{ 
    private string data1; 
    private string data2; 

    *getters and setters* 
} 
... 
final CommonData data = new CommonData(); 
Observable 
    .from(modifications) 
    .flatmap((data1) -> { 
     data.setData1(data1); 
     return op1(data1); 
    }) 
    ... 
    .flatmap((data2) -> { 
     data2 = data.getData1() + "data 2... "; 
     data.setData2(data2); 
     return op2(data2); 
    }) 

speranza che aiuta

+1

Sfortunatamente questo probabilmente non è thread-safe (a seconda del tuo codice RxJava eseguirà il calcolo su più thread) –

+0

sono confuso, perché una variabile privata non statica essere thread- "non sicuro" – josesuero

+0

Se RxJava crea più thread per flatmap() i tuoi dati, l'istanza di CommonData sarà condivisa tra i thread anche se non è statica. (Questo dovrebbe essere testabile con qualche logging che visualizza il thread corrente ei valori CommonData) –