Ich möchte einen EventBus mit RxJava implementieren und ich brauche klebrige Ereignisse. Ich weiß, dass ich ein BehaviorSubject verwenden kann, aber es speichert nur das letzte ausgegebene Element, während ich alle Ereignisse zwischenspeichern möchte, die sich durch ihren Typ unterscheiden (Klassenname). Es gibt eine andere Option - ReplaySubject, aber es hat einen Overhead - es enthält alle emittierten Elemente. Gibt es eine Möglichkeit, eine Art ReplaySubject zu erstellen, das nur nach Typelementen enthalten ist?ReplaySubject mit verschiedenen Elementen
Antwort
Ich glaube nicht, dass es saubere Lösungen gibt. Sie können dies jedoch möglicherweise durchführen.
- Erstellen Sie für jeden Ereignistyp eine
BehaviorSubject<>
. Verwenden Sie eineConcurrentMap
, um jedes eingehende Ereignis an die richtigeSubject
zu senden. - Pflegen Sie eine Liste dieser Themen in der Reihenfolge der Ankunft von Ereignissen.
- Wenn eine neue Subskription empfangen wird, wird eine Observable erstellt, die die Zusammenführung aller Subjekte mit der ersten Liste von Subjekten, die bereits Events erhalten haben, gefolgt von denen, die nicht in einer Reihenfolge sind.
Dies ist ein Code, der das obige klären könnte. Ungetestet.
// The subscription operation will perform a merge of the two lists
Map<EventType, BehaviorSubject<Event>> map = new ConcurrentHashMap<>();
List<BehaviorSubject<Event>> listOfUnseenEvents = new ArrayList<>();
List<BehaviorSubject<Event>> listOfSeenEvents = new ArrayList<>();
// ...
listOfUnseenEvents = map.values().asList();
public Observable<Event> busSub() {
List<BehaviorSubject<Event>> allEvents = new ArrayList<>();
synchronized (map) {
allEvents.addAll(listOfSeenEvents);
allEvents.addAll(listOfUnseenEvents);
}
return Observable.merge(allEvents);
}
// receive an event and dispatch it
eventSource
.subscribe(event -> processEvent(event));
public void processEvent(Event event) {
BehaviorSubject<Event> eSubject = map.get(event.getEventType());
synchronized (map) {
if (containsEventType(listOfSeenEvents, event.getEventType())) {
removeEventType(listOfSeenEvents, event.getEventType());
} else {
removeEventType(listOfUnseenEvents, event.getEventType());
}
listOfSeenEvents.add(eSubject);
}
eSubject.onNext(event);
}
Bitte beachten Sie, dass dieser Code sich die Tatsache zunutze, dass nimmt merge()
zu jedem der gegebenen Observablen um abonnieren werden. Dafür gibt es keine Garantie in der RxJava-Dokumentation.
Wenn nicht alle Ereignistypen im Voraus bekannt sind, funktioniert dies nicht.
Danke für die Idee, ich muss nicht zwischen gesehenen und ungesehenen Ereignissen unterscheiden, also könnte es vereinfacht werden. Auch warum funktioniert das nicht, wenn alle Ereignistypen unbestimmt sind? Ich kann Ereignisse nach ihrem Typ gruppieren und es scheint genug zu sein, um nur das letzte Ereignis des bestimmten Typs zu posten. – Buckstabue
Sie benötigen "ungesehene" Ereignis-Themen, damit Teilnehmer schließlich Ereignisse für diese Typen sehen. Andernfalls müssten Sie für jeden Abonnenten ein "nicht klassifiziertes" Subjekt und eine Liste von Ereignistypen haben, die in nicht klassifizierte fallen. –
- 1. Async Rohr aus ReplaySubject
- 2. So verwenden ReplaySubject in ReactiveKit
- 3. rxjs5/Angular - Clear ReplaySubject Puffer
- 4. Schleife durch div mit verschiedenen Elementen
- 5. Retrofit: Parst JSON mit verschiedenen Array-Elementen
- 6. HTML: Verbinden mit Elementen aus verschiedenen SVGs
- 7. XPath mit mehreren enthält auf verschiedenen Elementen
- 8. XSLT-Gruppe mit 2 verschiedenen Elementen
- 9. Verknüpfen mit Elementen in verschiedenen Dokumenten
- 10. RxJs Wie Ausnahme in ReplaySubject auslösen?
- 11. 2D-Array mit verschiedenen Arten von Elementen und mit Klassen
- 12. Jquery vergleichen zwei String aus verschiedenen Elementen
- 13. Erwartete unqualifizierte ID vor verschiedenen Elementen
- 14. erstellen Sie mehrere Arrays auf verschiedenen Elementen
- 15. Linq - Ausschließen von Elementen aus verschiedenen Listentypen
- 16. Zwei addEventListener-Funktionen auf zwei verschiedenen Elementen
- 17. Vergleichen von Elementen aus zwei verschiedenen Listen
- 18. Füllen Array mit Elementen aus verschiedenen HTML-Attributen
- 19. flat_map in Rubin bei der Arbeit mit verschiedenen Elementen
- 20. Verbinden Sie XML-Daten aus verschiedenen Elementen mit Transact-SQL
- 21. jquery synchrones Ausblenden und Fadeto mit verschiedenen Elementen
- 22. Deserialize XML mit verschiedenen Elementen auf getrennte Listen
- 23. PHP-Array mit verschiedenen Elementen (wie Python-Set)
- 24. Deserialize XML-Sammlung mit möglichen verschiedenen Elementen aber derselben Klasse
- 25. Formatierung der Ausgabe mit verschiedenen Elementen des gleichen Tupels
- 26. Fügen Sie verschiedene Klassen zu verschiedenen Elementen mit .hover() hinzu.
- 27. Wie man eine Komponente mit zwei verschiedenen Zuständen in zwei verschiedenen Elementen in React rendert?
- 28. Wie konvertiert man ein Observable zu einem ReplaySubject in RxJS?
- 29. Wie bekomme ich den letzten Wert von einem ReplaySubject?
- 30. Erste Kombinationen von Elementen aus aus verschiedenen Pandas Reihen
Sie können die Elemente filtern, bevor Sie sie im Betreff ausgeben. Sie werden also nach ihrem Typ bereits eindeutig sein, wenn sie im 'Betreff' empfangen werden. – masp
@masp es ist ein Event-Bus. Es ist wie ein unendlicher Strom. Ich weiß nicht, wie viele Elemente ich aussenden werde, daher kann ich sie nicht sammeln und filtern, bevor ich sie an ein Thema sende. – Buckstabue
Sie möchten das neueste Element nach Typ zwischenspeichern? Dann haben Sie mehrere BehaviorSubjects oder ReplaySubjects, einen für jeden Typ, der Ihnen auch Typsicherheit gibt. – akarnokd