我有一个主题用作事件总线。该总线发出多个项目,所有项目都是常见的类型:
static class EventBus {
private final Subject<Event> subject = BehaviorSubject.create();
/**
* @param event Event to publish to the subject
*/
void publish(@NonNull Event event) {
this.subject.onNext(event);
}
/**
* Listen to events of a specific class
*
* @param eventClass class of event to listen for
* @param <T> generic type
* @return Observable
*/
<T extends Event> Observable<T> listenForEvents(@NonNull Class<T> eventClass) {
return this.subject
.serialize()
.filter(eventClass::isInstance)
.cast(eventClass);
}
}
abstract static class Event {
int id;
public Event(int id) {
this.id = id;
}
}
final class EventA extends Event {
EventA(int id) {
super(id);
}
}
final class EventB extends Event {
EventB(int id) {
super(id);
}
}
想要监听特定事件的事物可以调用listenForEvents
并传递他们想要监听的类。
但是我希望每种类类型的 BehaviorSubject行为。一个示例将说明这一点:
void main() {
EventBus eventBus = new EventBus();
// publish some A's
eventBus.publish(new EventA(1));
eventBus.publish(new EventA(2));
eventBus.publish(new EventA(3));
// publish a B
eventBus.publish(new EventB(4));
eventBus.listenForEvents(EventA.class)
.subscribe(eventA -> {
// 1. I want to receive EventA(3) but I won't receive
// anything because last value in the BehaviorSubject is an EventB
Log.d("TAG", String.valueOf(eventA.id));
});
eventBus.publish(new EventA(5));
// 2. It's only if I put another EventA into the subject
// after I subscribe that I'll seen anything emitted.
}
我有几种可能的解决方案,但似乎都不是好方法=)
1。)多个BehaviorSubject,每个事件类型一个;这些可以偷懒创建的
2。)在可观察到的流之外跟踪“类型X的最新事件”
3。)将BehaviorSubject
转换为ReplaySubject
并使用.debounce(10, TimeUnit.MILLISECONDS)
,并假定重放的项目将很快发出,而新的项目将不会很快发布
private final Subject<Event> subject = ReplaySubject.create();
<T extends Event> Observable<T> listenForEvents(@NonNull Class<T> eventClass) {
return this.subject
.serialize()
.filter(eventClass::isInstance)
.cast(eventClass)
.debounce(10, TimeUnit.MILLISECONDS);
}
是否可以使用现有的rx运算符来执行此操作?