Item子类的BehaviorSubject功能

时间:2018-07-02 23:57:32

标签: rx-java2

我有一个主题用作事件总线。该总线发出多个项目,所有项目都是常见的类型:

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运算符来执行此操作?

0 个答案:

没有答案