Yo soy el encadenamiento de las operaciones asincrónicas utilizando RxJava, y me gustaría pasar una variable de abajo:

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

Parece un patrón común, pero no pude encontrar información sobre ella.

InformationsquelleAutor Julian Go | 2015-01-27

7 Comentarios

  1. 55

    Los consejos que he recibido de Couchbase foro es para uso anidada observables:

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

    EDIT: voy a marcar este como el aceptado como respuesta parece ser la más recomendable. Si su proceso es demasiado complejo para anidar todo lo que usted puede también comprobar la solución con la función de llamadas.

    • Esto es lo que me encuentro haciendo a menudo, y ha funcionado bien hasta ahora.
  2. 13

    Otra posibilidad es asignar el resultado de op1 a un org.apache.commons.lang3.tuple.Pair que contiene la variable y pasar a lo largo de:

    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());
       })

    Funciona, pero se siente un poco incómodo tener variables ocultas dentro de un Par/Triple/… y se pone muy detallado si utiliza el Java 6 notación.

    Me pregunto si hay una solución mejor, tal vez algunos RxJava operador podría ayudar?

    • Yo no creo que haya nada malo en hacer esto, pero cada vez que siento que necesito para llegar a la Par de la clase, yo también siento que estoy haciendo algo mal. La cantidad de veces que lo he utilizado, y, a continuación, volver a factores más tarde una vez que tengo una mejor comprensión acerca de mi dominio.
    • Esta es la solución que se me ocurrió, a pesar de que sería crear una tonelada de basura para hacer Pair instancias sólo para mantener data1 junto a obj. Me pregunto si un combine iba a funcionar.
  3. 5

    Una posibilidad sería el uso de una llamada a una función:

    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); })

    PERO: me corrija si estoy equivocado, pero no se siente como la reactiva, programación manera de hacerlo

    • Es esto muy diferente que su primera opción?
    • sí, supongo que es functionnaly similar a la utilización de las llamadas anidadas. Para el procesamiento complejo probablemente no es una mala opción, después de todo.
  4. 1

    solución en este hilo funciona, pero para los complejos de cadenas, código difícil de leer, tuve que pasar varios valores y lo que hice fue crear una clase privada con todos los parámetros, puedo encontrar el código sea más legible de esta manera,

    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);
       })

    espero que ayude

    • Por desgracia, esto probablemente no es thread-safe (dependiendo de su código RxJava se ejecutará el cálculo en varios subprocesos)
    • estoy confundido, ¿por qué un privado,no variable estática ser de hilo de»inseguro»
    • Si RxJava crea varios subprocesos para flatmap() sus datos, el CommonData instancia será compartida entre los hilos, incluso si no es estática. (Esto debe ser comprobable con algunas de registro que muestra el subproceso actual y la CommonData valores)
    • Tengo que encontrar otra solución, porque si tienes que hacer algo como: si (boolean) retorno observer1 else return observer2; tendría que flatmap en tanto que sería mal..
  5. 1

    Puede utilizar «global» de la variable para lograr esto:

     Object[] data1Wrapper = new Object[]{null};
     Object[] data2Wrapper = new Object[]{null};
     Observable
        .from(modifications)
        .flatmap(data1 -> {
            data1Wrapper[0] = data1;
            return op1(data1)
         })
          ...
        .flatmap(data2 -> { 
            //I can access data1 here use data1Wrapper[0]
            Object data1 = data1Wrapper[0];
            data2Wrapper[0] = data2;
            return op2(data2);
         })
  6. 0

    Sé que esta es una vieja cuestión, pero el uso de RxJava2 & lambda,
    Usted puede usar algo como:

    Observable
    .from(modifications)
    .flatMap((Function<Data1, ObservableSource<Data2>>) data1 -> {
                            //Get data 2 obeservable
    
                                return Observable.just(new Data2())
                            }
                        }, Pair::of)

    En el siguiente flujo (flatmap/mapa) a su par de salida será (data1, data2)

Dejar respuesta

Please enter your comment!
Please enter your name here