Próbuję zastąpić mój kod przez rx-java. (Jest to bardzo mały kod.)Jak zamienić "if statement" na rx-java, aby uniknąć piekła wywołania zwrotnego?
Jest gotowy i działa.
Ale chcę wiedzieć ...
- Czy to dobry styl Rx?
- Jeśli nie dobry, proszę wskazać zły punkt
Poniżej jest mój kod, który jest obsługa api.
przed
Random r = new Random();
boolean apiResult = r.nextBoolean(); // it represents api result. ex. {"result": true} or {"result": false}
if (apiResult == true) {
// do something
System.out.println("result:" + "success");
} else {
// do something
System.out.println("result:" + "failure");
}
po
Random r = new Random();
Observable<Boolean> apiResultStream = Observable.create(new OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
// emit true or false
subscriber.onNext(r.nextBoolean());
}
}).cache(1);
// I used filter for split. Is it Rx style?
// success if true emitted.
Observable<Boolean> successStream = apiResultStream
.filter(aBoolean -> aBoolean == true); // here
// failure if false emitted.
Observable<Boolean> failureStream = apiResultStream
.filter(aBoolean -> aBoolean == false); // here
// success flow
successStream
.flatMap(aBoolean -> Observable.just("success"))
// and do something
.subscribe(aString -> System.out.println("result:" + aString));
// failure flow
failureStream
.flatMap(aBoolean -> Observable.just("failure"))
// and do something.
// I want to keep subscriber.
.subscribe(aString -> System.out.println("result:" + aString));
EDIT
prawie wymienić. thanks for good comment.
(ale mam kilka niezmienionych kodów, ma wiele callback i jeśli instrukcja.)
Chcę uniknąć "piekła oddzwonienia".
Kluczem jest inny typ wynik między 'callSuccessApi' i 'callFailureApi'
przed RX
// callback hell!
callApi(new Callback<Result>(){
@Override
public void success(Result result) {
if (result.Response == true) {
callSuccessApi(new Callback<ResultSuccess>(){
@Override
public void success(ResultSuccess result) {
// and more callbacks...
}
}
} else { // result.Response == false
callFailureApi(new Callback<ResultFailure>(){
@Override
public void success(ResultFailure result) {
// and more callbacks...
}
}
}
}
}
po Rx (unikać oddzwonienia piekła! Czy to dobry styl Rx?)
// change 1st api to observable.(I changed other api to observable)
Observable<Result> apiResultStream = Observable.create(new OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
callApi(new Callback<Result>(){
@Override
public void success(Result result) {
subscriber.onNext(result);
}
});
}
}).cache(1); // ensure same Observable<Result> for success and failure.
// I used filter for split. Is it Rx style?
// success if result.response == true.
Observable<ResultSuccess> successStream = apiResultStream
.filter(result -> result.response == true); // here
// failure if result.response == false.
Observable<ResultFailure> failureStream = apiResultStream
.filter(result -> result.response == false); // here
// success flow. callSuccessApi return Observable<ResultSuccess>
successStream
.flatMap(result -> callSuccessApi(result))
// and more api call with flatMap...
.subscribe(resultSuccessN -> System.out.println("result:" + resultSuccessN.toString()));
// failure flow. callFailureApi return Observable<ResultFailure>
failureStream
.flatMap(resultFailure -> callFailureApi(result))
// and more api call with flatMap...
.subscribe(resultFailureN -> System.out.println("result:" + resultFailureN.toString()));
Przepraszam za moje słabe angielskie i długie pytanie.
Updated mój kod
mam 2 ważne informacje w tej sprawie. (Dziękuję @ Tomáš Dvořák, @Will
- czy jest to dobry sposób, aby przejść zależy od konkretnej sytuacji .
- Nie ma nic złego w używaniu if ramach mapie/flatmap/subskrybować.
zaktualizowany kod:
Observable<Result> apiResultStream = Observable.create(new OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
callApi(new Callback<Result>() {
@Override
public void success(Result result) {
subscriber.onNext(result);
}
});
}
});
// In this case, I used 'if' for simply and cleanly.
apiResultStream
.subscribe(result -> {
if (result.response == true) {
callSuccessApi(); // this line looks like 'callback'. but I used this for simply and cleanly.
} else {
callFailureApi();
}
});
Konkretne użycie operatorów zależy od sytuacji. Idź z najprostszym rozwiązaniem, w tym przypadku 'apiResultStream.subscribe (aBoolean -> if (aBoolean) {doSomething} else {doSomethingElse}. Dzięki takiemu podejściu nie musisz nawet tego buforować (co i tak było nieparzyste). Trudno polecić więcej, gdy nie wiemy, co chcesz osiągnąć: –
dzięki dobrej radzie zaktualizowałem pytanie "unikam piekła oddzwonienia" – kyanro
Nawet po aktualizacji problem, który przedstawiłeś, polega na tym, że chcesz wykonać jedno z dwóch działań powodujących efekt uboczny w zależności od wartości obserwowanej wartości boolowskiej Moje proste rozwiązanie nadal obowiązuje i rozwiązuje twój przykład w prosty i czysty sposób Jeśli faktycznie masz inny problem do rozwiązania, opublikuj go Btw, oczywiście może użyć 'filtru', aby podzielić przepływ, ale znowu, czy jest to dobry sposób na odejście, zależy od konkretnej sytuacji. –