rx-java
Operatorzy
Szukaj…
Uwagi
Ten dokument opisuje podstawowe zachowanie operatora.
Operatory, wprowadzenie
Za pomocą operatora można manipulować przepływem obiektów z Observable na 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);
Dane wyjściowe będą:
onNext called with: one
onNext called with: two
onNext called with: three
onCompleted called!
Operator map zmienił liczbę Integer możliwą do zaobserwowania na wartość String obserwowalną, tym samym manipulując przepływem obiektów.
Łączenie operatorów
Można połączyć chained sobą wielu operatorów, aby uzyskać mocniejsze transformacje i manipulacje.
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
Między Observable a Subscriber można dodać dowolną liczbę operatorów.
Operator flatMap
Operator flatMap pomaga przekształcić jedno zdarzenie w inne Observable (lub przekształcić zdarzenie w zero, jedno lub więcej zdarzeń).
Jest to idealny operator, gdy chcesz wywołać inną metodę, która zwraca Observable
public Observable<String> perform(int i) {
// ...
}
Observable.just(1, 2, 3)
.flatMap(i -> perform(i))
.subscribe(result -> System.out.println("result ->" + result);
flatMap serializuje subskrypcje perform ale zdarzenia emitowane przez perform mogą nie być zamawiane. Możesz więc otrzymywać zdarzenia emitowane przez ostatnie wykonanie połączenia przed zdarzeniami z pierwszego perform połączenia (zamiast tego należy użyć concatMap ).
Jeśli tworzysz kolejną Observable w swoim subskrybencie, powinieneś użyć flatMap . Główną ideą jest: nigdy nie zostawiaj Obserwowalnego
Na przykład :
Observable.just(1, 2, 3)
.subscribe(i -> perform(i));
można łatwo zastąpić:
Observable.just(1, 2, 3)
.flatMap(i -> perform(i))
.subscribe();
Dokumentacja Reactivex.io: http://reactivex.io/documentation/operators/flatmap.html
filtr operatora
Za pomocą operatora filter można odfiltrować elementy ze strumienia wartości na podstawie wyniku metody predykatu.
Innymi słowy, elementy przekazywane od obserwatora do subskrybenta zostaną odrzucone na podstawie filter Funkcja, którą przekazujesz, jeśli funkcja zwraca wartość false dla określonej wartości, wartość ta zostanie odfiltrowana.
Przykład:
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
});
Ten kod zostanie wydrukowany
0.0
4.0
16.0
36.0
64.0
operator mapy
Za pomocą operatora map można odwzorować wartości strumienia na różne wartości na podstawie wyniku dla każdej wartości z funkcji przekazanej do map . Strumień wynikowy jest nową kopią i nie zmodyfikuje dostarczonego strumienia wartości, strumień wynikowy będzie miał tę samą długość strumienia wejściowego, ale może być różnego typu.
Funkcja przekazana do .map() musi zwrócić wartość.
Przykład:
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
});
Ten kod zostanie wydrukowany
"1"
"2"
"3"
W tym przykładzie Observable zaakceptował List<Integer> lista zostanie przekształcona w List<String> w potoku, a .subscribe wyemituje String
operator doOnNext
operator doOnNext wywoływany za każdym razem, gdy źródło Observable emituje element. Można go używać do celów debugowania, wykonywania niektórych działań względem emitowanego elementu, rejestrowania itp.
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();
W poniższym przykładzie doOnNext nigdy nie jest wywoływany, ponieważ source Observable nic nie emituje, ponieważ Observable.empty() wywołuje onCompleted po subskrybowaniu.
Observable.empty()
.doOnNext(item -> System.out.println("item: " + item))
.subscribe();
powtórz operator
operator repeat pozwala powtórzyć całą sekwencję ze źródła Observable .
Observable.just(1, 2, 3)
.repeat()
.subscribe(
next -> System.out.println("next: " + next),
error -> System.out.println("error: " + error),
() -> System.out.println("complete")
);
Wynik powyższego przykładu
next: 1
next: 2
next: 3
next: 1
next: 2
next: 3
Ta sekwencja powtarza się nieskończoną liczbę razy i nigdy się nie kończy.
Aby powtórzyć sekwencję skończoną liczbę razy, wystarczy podać liczbę całkowitą jako argument do repeat operatora.
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")
);
Ten przykład jest drukowany
next: 1
next: 2
next: 3
next: 1
next: 2
next: 3
next: 1
next: 2
next: 3
complete
Bardzo ważne jest, aby zrozumieć, że operator repeat subskrybuje źródło Observable po zakończeniu sekwencji Źródło Observable . Przepiszmy przykład powyżej, używając 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")
);
Ten przykład jest drukowany
Subscribed
next: 1
next: 2
next: 3
Subscribed
next: 1
next: 2
next: 3
Subscribed
next: 1
next: 2
next: 3
complete
Podczas korzystania z operatorem łączenia ważne jest, aby wiedzieć, że repeat operator powtórzy całą sekwencję niż poprzedzający operatora.
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")
);
Ten przykład jest drukowany
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
Ten przykład pokazuje, że repeat operator powtarza całą sekwencję odnów subskrypcję do Observable zamiast powtarzania ostatniego map operatora i nie ma znaczenia, w którym miejscu w sekwencji repeat operatora użyte.
Ta sekwencja
Observable.<Integer>create(subscriber -> {
//...
})
.map(value -> value * 2) //First chain operator
.map(value -> "modified " + value) //Second chain operator
.repeat(3)
.subscribe(
/*....*/
);
jest równy tej sekwencji
Observable.<Integer>create(subscriber -> {
//...
})
.repeat(3)
.map(value -> value * 2) //First chain operator
.map(value -> "modified " + value) //Second chain operator
.subscribe(
/*....*/
);