Ich versuche, meinen Code durch RX-Java zu ersetzen. (Es ist sehr kleiner Code.)Wie 'If-Anweisung' mit RX-Java zu ersetzen, um Rückruf-Hölle zu vermeiden?
Es ist fertig und es funktioniert.
Aber ich möchte wissen, ...
- Ist es ein guter Stil Rx?
- Wenn nicht gut, geben Sie bitte schlechten Punkt
Unten ist mein Code, die api Handhabung ist.
vor
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");
}
nach
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
ich fast ersetzt. thanks for good comment.
(aber ich habe ein paar nicht-Code ersetzt. Es hat viele Rückruf und wenn Äußerung.)
Ich will ‚Hölle Rückruf‘ vermeiden.
Der Schlüssel ist, unterschiedlichen Ergebnistyp zwischen 'callSuccessApi' und 'callFailureApi'
vor 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...
}
}
}
}
}
nach mit rx (Rückruf Hölle vermeiden! Ist es ein guter Rx Stil?)
// 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()));
Entschuldigung für meine schlechte Englisch und lange Frage.
Mein Code aktualisiert
Ich habe 2 wichtige Informationen in dieser Frage. (Danke @ Tomáš Dvořák, @Will
- , ob es ein guter Weg, um auf die besondere Situation zu gehen depends .
- Es ist nichts falsch mit der Verwendung einer if-Anweisung innerhalb einer Karte/flatmap/abonnieren.
Aktualisierter Code
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();
}
});
Konkrete Verwendung der Operatoren hängt von der Situation ab. Gehen Sie mit der einfachsten Lösung, in diesem Fall 'apiResultStream.subscribe (aBoolean -> if (aBoolean) {doSomething} else {doSomethingElse}'. Mit diesem Ansatz müssen Sie nicht einmal im Cache (was sowieso ungerade war). Es ist schwer, mehr zu empfehlen, wenn wir nicht wissen, was Sie erreichen möchten. –
danke guten Rat. Ich aktualisierte Frage zu "Callback-Hölle vermeiden." – kyanro
Auch nach Ihrem Update ist das Problem, das Sie vorgestellt haben, dass Sie durchführen möchten Eine der beiden Nebeneffekte hängt vom Wert der booleschen Observablen ab.Meine einfache Lösung gilt und löst Ihr Beispiel einfach und sauber.Wenn Sie tatsächlich ein anderes Problem zu lösen haben, bitte posten Sie das. Übrigens natürlich Sie kann 'filter' verwenden, um den Fluss zu teilen, aber wiederum, ob es ein guter Weg ist, hängt von der jeweiligen Situation ab. –