rx-java
Los operadores
Buscar..
Observaciones
Este documento describe el comportamiento básico de un operador.
Operadores, una introducción
Se puede usar un operador para manipular el flujo de objetos de Observable a Subscriber .
Observable<Integer> integerObservable = Observable.just(1, 2, 3); // creating a simple Integer observable
Subscriber<String> mSubscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("onCompleted called!");
}
@Override
public void onError(Throwable throwable) {
System.out.println("onError called");
}
@Override
public void onNext(String string) {
System.out.println("onNext called with: " + string);
}
}; // a simple String subscriber
integerObservable
.map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
switch (integer) {
case 1:
return "one";
case 2:
return "two";
case 3:
return "three";
default:
return "zero";
}
}
}).subscribe(mSubscriber);
La salida sería:
onNext called with: one
onNext called with: two
onNext called with: three
onCompleted called!
El operador del map cambió el Integer observable a una String observable, manipulando así el flujo de objetos.
Encadenamiento del operador
Se pueden chained varios operadores para obtener transformaciones y manipulaciones más poderosas.
integerObservable // emits 1, 2, 3
.map(i -> i + 10) // adds 10 to each item; emits 11, 12, 13
.filter(i -> i > 11) // emits items that satisfy condition; 12, 13
.last() // emits last item in observable; 13
// unlimited operators can be added ...
.subscribe(System.out::println); // prints 13
Se puede agregar cualquier número de operadores entre el Observable y el Subscriber .
Operador FlatMap
El operador flatMap ayuda a transformar un evento en otro Observable (o transformar un evento en cero, uno o más eventos).
Es un operador perfecto cuando desea llamar a otro método que devuelve un Observable
public Observable<String> perform(int i) {
// ...
}
Observable.just(1, 2, 3)
.flatMap(i -> perform(i))
.subscribe(result -> System.out.println("result ->" + result);
flatMap serializará las suscripciones de perform pero los eventos emitidos por perform pueden no ordenarse. Por lo que puede recibir eventos emitidos por la última llamada antes de realizar eventos desde el primer perform llamadas (que puedes usar concatMap en su lugar).
Si está creando otro Observable en su suscriptor, debe utilizar flatMap en flatMap lugar. La idea principal es: nunca dejar lo observable.
Por ejemplo :
Observable.just(1, 2, 3)
.subscribe(i -> perform(i));
Se puede reemplazar fácilmente por:
Observable.just(1, 2, 3)
.flatMap(i -> perform(i))
.subscribe();
Documentación de Reactivex.io: http://reactivex.io/documentation/operators/flatmap.html
Operador de filtro
Se puede utilizar el filter operador para filtrar los elementos de la corriente de valores basado en el resultado de un método predicado.
En otras palabras, los elementos que pasan del Observador al Suscriptor se descartarán en función de la Función que pase el filter , si la función devuelve false para un determinado valor, ese valor se eliminará.
Ejemplo:
List<Integer> integers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
Observable.from(integers)
.filter(number -> {
return (number % 2 == 0);
// odd numbers will return false, that will cause them to be filtered
})
.map(i -> {
return Math.pow(i, 2); // take each number and multiply by power of 2
})
.subscribe(onNext -> {
System.out.println(onNext); // print out the remaining numbers
});
Este código se imprimirá
0.0
4.0
16.0
36.0
64.0
operador de mapas
Se puede utilizar el map operador para asignar los valores de una corriente a diferentes valores basados en los resultados para cada valor de la función pasada a map . El flujo de resultados es una nueva copia y no modificará el flujo de valores proporcionado, el flujo de resultados tendrá la misma longitud del flujo de entrada, pero puede ser de diferentes tipos.
La función pasada a .map() , debe devolver un valor.
Ejemplo:
List<Integer> numbers = Arrays.asList(1, 2, 3);
Observable.from(numbers)
.map(number -> {
return number.toString(); // convert each integer into a string and return it
})
.subscribe(onNext -> {
System.out.println(onNext); // print out the strings
});
Este código se imprimirá
"1"
"2"
"3"
En este ejemplo, el Observable aceptó una List<Integer> la lista se transformará en una List<String> en la tubería y el .subscribe emitirá String
Operador doOnNext
doOnNext operador doOnNext llama cada vez que la fuente Observable emite un elemento. Se puede utilizar para fines de depuración, aplicando alguna acción al elemento emitido, al registro, etc.
Observable.range(1, 3)
.doOnNext(value -> System.out.println("before transform: " + value))
.map(value -> value * 2)
.doOnNext(value -> System.out.println("after transform: " + value))
.subscribe();
En el siguiente ejemplo, nunca se llama a doOnNext porque la fuente Observable no emite nada porque Observable.empty() llama onCompleted después de suscribirse.
Observable.empty()
.doOnNext(item -> System.out.println("item: " + item))
.subscribe();
operador de repetición
repeat operador de repeat permite repetir una secuencia completa desde la fuente Observable .
Observable.just(1, 2, 3)
.repeat()
.subscribe(
next -> System.out.println("next: " + next),
error -> System.out.println("error: " + error),
() -> System.out.println("complete")
);
Salida del ejemplo anterior.
next: 1
next: 2
next: 3
next: 1
next: 2
next: 3
Esta secuencia se repite un número infinito de veces y nunca se completa.
Para repetir un número finito de secuencias, simplemente pase un entero como argumento para repeat operador.
Observable.just(1, 2, 3)
// Repeat three times and complete
.repeat(3)
.subscribe(
next -> System.out.println("next: " + next),
error -> System.out.println("error: " + error),
() -> System.out.println("complete")
);
Este ejemplo imprime
next: 1
next: 2
next: 3
next: 1
next: 2
next: 3
next: 1
next: 2
next: 3
complete
Es muy importante comprender que el operador repeat vuelve a suscribirse a la fuente Observable cuando se completa la secuencia Observable fuente. Reescribamos el ejemplo anterior usando Observable.create .
Observable.<Integer>create(subscriber -> {
//Same as Observable.just(1, 2, 3) but with output message
System.out.println("Subscribed");
subscriber.onNext(1);
subscriber.onNext(2);
subscriber.onNext(3);
subscriber.onCompleted();
})
.repeat(3)
.subscribe(
next -> System.out.println("next: " + next),
error -> System.out.println("error: " + error),
() -> System.out.println("complete")
);
Este ejemplo imprime
Subscribed
next: 1
next: 2
next: 3
Subscribed
next: 1
next: 2
next: 3
Subscribed
next: 1
next: 2
next: 3
complete
Cuando se utiliza el operador de encadenamiento es importante saber que repeat operador repite toda la secuencia anterior en lugar de operador.
Observable.<Integer>create(subscriber -> {
System.out.println("Subscribed");
subscriber.onNext(1);
subscriber.onNext(2);
subscriber.onNext(3);
subscriber.onCompleted();
})
.map(value -> value * 2) //First chain operator
.map(value -> "modified " + value) //Second chain operator
.repeat(3)
.subscribe(
next -> System.out.println("next: " + next),
error -> System.out.println("error: " + error),
() -> System.out.println("complete")
);
Este ejemplo imprime
Subscribed
next: modified 2
next: modified 4
next: modified 6
Subscribed
next: modified 2
next: modified 4
next: modified 6
Subscribed
next: modified 2
next: modified 4
next: modified 6
complete
Este ejemplo muestra que repeat operador repite toda la secuencia resubscribing a Observable en lugar de repetir último map operador y no importa en que lugar en la secuencia repeat operador utilizado.
Esta secuencia
Observable.<Integer>create(subscriber -> {
//...
})
.map(value -> value * 2) //First chain operator
.map(value -> "modified " + value) //Second chain operator
.repeat(3)
.subscribe(
/*....*/
);
es igual a esta secuencia
Observable.<Integer>create(subscriber -> {
//...
})
.repeat(3)
.map(value -> value * 2) //First chain operator
.map(value -> "modified " + value) //Second chain operator
.subscribe(
/*....*/
);