Próbuję przeprowadzić migrację z RxJava1 do RxJava2. Zastępuję wszystkie części kodu, w których poprzednio miałem Observable<Void>
do Compleatable
. Jednak wystąpił jeden problem z kolejnością wywołań strumieniowych. Kiedy poprzednio zajmowałem się Observables i korzystałem z map i płaskich map, kod działał "zgodnie z oczekiwaniami". Jednak operator andthen()
wydaje się działać nieco inaczej. Oto przykładowy kod upraszczający sam problem.Kolejność wywołań RxJava2 z wykonalnym operatorem i operatorem
public Single<String> getString() {
Log.d("Starting flow..")
return getCompletable().andThen(getSingle());
}
public Completable getCompletable() {
Log.d("calling getCompletable");
return Completable.create(e -> {
Log.d("doing actuall completable work");
e.onComplete();
}
);
}
public Single<String> getSingle() {
Log.d("calling getSingle");
if(conditionBasedOnActualCompletableWork) {
return getSingleA();
}else{
return getSingleB();
}
}
Co widzę w dziennikach w końcu jest:
1-> Log.d("Starting flow..")
2-> Log.d("calling getCompletable");
3-> Log.d("calling getSingle");
4-> Log.d("doing actuall completable work");
I jak można chyba wymyślić spodziewałbym linia 4 zostać wywołana przed linii 3 (później nazwa andthen()
operatora sugerują, że kod będzie nazywać się "po" Komplecie kończy pracę). Wcześniej tworzyłem Observable<Void>
używając operatora Async.toAsync()
, a metoda, która jest teraz nazywana getSingle
była w strumieniu flatMap
- działała tak, jak oczekiwałam, więc Log 4 pojawił się przed 3. Teraz próbowałem zmienić sposób, w jaki jest tworzony Compleatable - jak przy użyciu fromAction
lub fromCallable
, ale zachowuje się tak samo. Nie mogłem też znaleźć innego operatora, który mógłby zastąpić andthen()
. Podkreślenie - metoda musi być Completable, ponieważ nie ma żadnej rzeczy, która w pełni powróciłaby do formy - zmienia preferencje aplikacji i inne ustawienia (i jest używana tak, jak na całym świecie w większości działa "zgodnie z oczekiwaniami"), a te zmiany są potrzebne później w strumieniu. Próbowałem też owinąć metodę getSingle()
, aby w jakiś sposób utworzyć Single i przenieść instrukcję if wewnątrz bloku create, ale nie wiem jak używać metod getSingleA/B(). I potrzebuję ich użyć, ponieważ mają swoją złożoność i nie ma sensu powielać kodu. Ktoś ma jakiś pomysł, jak to zmienić w RxJava2, więc zachowuje się tak samo? Istnieje wiele miejsc, w których polegam na pracy Compleatable, aby zakończyć, zanim przejdę do przodu ze strumieniem (jak odświeżanie tokena sesji, aktualizacja db, preferencje itd. - nie ma problemu w RxJava1 przy użyciu flatMap).
Czy rozumiesz, że wywołanie 'getSingle()' wykonuje się natychmiast, a nie po zakończeniu "Completable" zwróconego przez 'getCompletable'? – akarnokd