2017-09-04 33 views
0

我想用RxJava实现一个EventBus,我需要粘性事件。我知道我可以使用BehaviorSubject,但它只缓存最后发出的项目,而我想缓存所有不同类型的事件(类名)。还有另一种选择 - ReplaySubject,但它有一个开销 - 它拥有所有发射的元素。 有没有一种方法来创建某种ReplaySubject,它只能通过类型元素保持唯一性?ReplaySubject不同的元素

+0

您可以在“主题”中发布它们之前过滤这些项目。因此,当它们在“主题”中收到时,它们将按类型已经是唯一的。 – masp

+0

@masp这是一个事件总线。这就像一个无限的流。我不知道我会发射多少物品,因此我无法收集它们并在将它们发送到主题之前进行过滤 – Buckstabue

+0

您想按类型缓存最新的元素吗?然后拥有多个BehaviorSubjects或ReplaySubjects,每种类型都可以为您提供类型安全性。 – akarnokd

回答

1

我不认为有任何清洁的解决方案。但是,您可能可以完成这项工作。

  1. 为每个事件类型创建一个BehaviorSubject<>。使用ConcurrentMap将每个传入事件分派到正确的Subject
  2. 按事件到达顺序维护这些主题的列表。
  3. 当收到新的订阅时,将创建一个可观察的事件,即所有主题的合并,第一个主题列表已经收到事件,第二个主题列表中的事件没有任何顺序。

这是一些代码,可能会澄清上述情况。未经测试。

// 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); 
} 

请注意,此代码利用了一个事实,即merge()将订阅每个给定的观测,以便优势。在RxJava文档中没有这样的保证。

如果事先不知道所有的事件类型,那么这将不起作用。

+0

感谢您的想法,我不需要区分看到和看不见的事件,所以它可以被简化,还有,如果所有事件类型都不确定,为什么这不起作用?我可以按事件类型对事件进行分组,似乎只发布特定类型的最新事件 – Buckstabue

+0

您需要“未看到”的事件主题,以便订阅者最终可以看到这些类型的事件。否则,您需要为每个订阅者提供“未分类”主题,以及属于未分类的事件类型列表。 –