Wie übergibt man in RxJava eine Variable beim Verketten von Observablen?
Lesezeit: 4 Minuten
Julian Go
Ich verkette asynchrone Operationen mit RxJava und möchte einige Variablen nachgelagert übergeben:
Observable
.from(modifications)
.flatmap( (data1) -> { return op1(data1); })
...
.flatmap( (data2) -> {
// How to access data1 here ?
return op2(data2);
})
Es scheint ein allgemeines Muster zu sein, aber ich konnte keine Informationen darüber finden.
Julian Go
Der Rat, den ich vom Couchbase-Forum erhalten habe, lautet, verschachtelte Observables zu verwenden:
Observable
.from(modifications)
.flatmap( (data1) -> {
return op1(data1)
...
.flatmap( (data2) -> {
// I can access data1 here
return op2(data2);
})
});
BEARBEITEN: Ich werde dies als akzeptierte Antwort markieren, da es die am meisten empfohlene zu sein scheint. Wenn Ihre Verarbeitung zu komplex ist, um alles zu verschachteln, können Sie die Lösung auch mit Funktionsaufrufen überprüfen.
Das mache ich oft und hat bisher gut funktioniert.
– Werden
6. Februar 2015 um 13:09 Uhr
Hm, das ist für mich nicht viel anders als “Daten außerhalb des Streams speichern”.
– ror
9. Juli 2020 um 17:41 Uhr
Eine andere Möglichkeit besteht darin, das Ergebnis zuzuordnen op1 zu einem org.apache.commons.lang3.tuple.Pair das die Variable enthält und weitergeben:
Es funktioniert, aber es fühlt sich etwas unangenehm an, Variablen in einem Pair/Triple/… versteckt zu haben, und es wird sehr ausführlich, wenn Sie die Java 6-Notation verwenden.
Ich frage mich, ob es eine bessere Lösung gibt, vielleicht könnte ein RxJava-Operator helfen?
Ich denke nicht, dass daran etwas falsch ist, aber immer wenn ich das Gefühl habe, dass ich nach dem Pair-Kurs greifen muss, habe ich auch das Gefühl, dass ich etwas falsch mache. Die Häufigkeit, mit der ich es verwendet und später wieder herausgearbeitet habe, sobald ich ein besseres Verständnis für meine Domäne habe.
– Werden
6. Februar 2015 um 13:13 Uhr
Dies ist die Lösung, die mir eingefallen ist, obwohl dies eine Menge Müll verursachen würde Pair Instanzen nur zu behalten data1 neben obj. Ich frage mich, ob a combine würde funktionieren.
Beim nächsten Flow (flatmap/map) ist Ihr Ausgabepaar (data1, data2)
josesuero
Lösung in diesem Thread funktioniert, aber für komplexe Ketten macht es Code schwer lesbar, ich musste mehrere Werte übergeben und was ich tat, war eine private Klasse mit allen Parametern zu erstellen, ich finde Code auf diese Weise besser lesbar,
private class CommonData{
private string data1;
private string data2;
*getters and setters*
}
...
final CommonData data = new CommonData();
Observable
.from(modifications)
.flatmap( (data1) -> {
data.setData1(data1);
return op1(data1);
})
...
.flatmap( (data2) -> {
data2 = data.getData1() + "data 2... ";
data.setData2(data2);
return op2(data2);
})
ich hoffe es hilft
Leider ist dies wahrscheinlich nicht Thread-sicher (abhängig von Ihrem Code führt RxJava Berechnungen in mehreren Threads aus).
– Julian Go
27. März 2017 um 8:38 Uhr
Ich bin verwirrt, warum sollte eine private, nicht statische Variable Thread-“unsicher” sein?
– josesuero
28. März 2017 um 21:00 Uhr
Wenn RxJava mehrere Threads zum Flatmap() Ihrer Daten erstellt, wird die CommonData-Instanz von den Threads gemeinsam genutzt, auch wenn sie nicht statisch ist. (Dies sollte mit einer Protokollierung testbar sein, die den aktuellen Thread und die CommonData-Werte anzeigt.)
– Julian Go
29. März 2017 um 14:08 Uhr
Ich muss eine andere Lösung finden, denn wenn Sie so etwas tun müssen: if (boolean) return Observer1 else return Observer2; Sie müssten auf beiden eine Flatmap erstellen, was … schlecht wäre
– josesuero
2. April 2017 um 18:43 Uhr
12550200cookie-checkWie übergibt man in RxJava eine Variable beim Verketten von Observablen?yes