RxJava-无法访问Observable的订阅者?

时间:2015-05-12 16:21:24

标签: java monads reactive-programming rx-java

我学会了it is undesirable在反应式编程中使用Subjects,尽管我发现它们非常方便。但我知道他们可能会受到虐待。因此,我尝试创建一个无限Observable<ImmutableMap<Integer,ActionProfile>,每次调用ImmutableMap时都需要发布新的refresh()。我还有一个forKey()方法,它返回Observable检索与特定密钥匹配的最新ActionProfile

然而,对于我如何处理订阅者而言,某些事情并不能让我们感到犹豫不决。我认为如果Observable的生命是无限的,你必须在Observable的建筑之外自己管理订户吗? Observable是否保留其订户列表?或者是我的责任,所以我可以随时打电话给他们onNext()

public final class ActionProfileManager {
    private final Observable<ImmutableMap<Integer,ActionProfile>> actionProfiles;
    private volatile ImmutableMap<Integer,ActionProfile> actionProfileMap;

    //do I really need this?
    private final CopyOnWriteArrayList<Subscriber<? super ImmutableMap<Integer,ActionProfile>>> subscribers = new CopyOnWriteArrayList<>();

    private ActionProfileManager() {
        this.actionProfiles = Observable.create(subscriber -> {
            subscriber.onNext(actionProfileMap);
            subscribers.add(subscriber); // is it up to me to capture the subscriber here or is it already saved somewhere for me?
        });
    }

    public void refresh() { 
        actionProfileMap = importFromDb();
        subscribers.forEach(s -> s.onNext(actionProfileMap));
    }

    public Observable<ActionProfile> forKey(int actionProfileId) { 
        return actionProfiles.map(m -> m.get(actionProfileId));
    } 
    private ImmutableMap<Integer,ActionProfile> importFromDb() { 
        return ImmutableMap.of(); //import data here
    }
}

1 个答案:

答案 0 :(得分:3)

Cold Observable通常一次与单个订阅者进行交互,即使您订阅了更多订阅者,它们也会独立运行,并不需要彼此了解。

另一方面,受试者必须在他们自己收到的多播事件中跟踪他们的订户。

快速查看代码表明存在一些竞争条件以及丢失通知的可能性。而不是它,你可以依赖BehaviorSubject这是异步词的'反应属性'。让它存储当前不可变的映射并处理订阅者:

BehaviorSubject<ImmutableMap> bs = BehaviorSubject.create();
Subject<ImmutableMap, ImmutableMap> sync = bs.toSerialized();

forKey(k): bs.map(m -> m.get(k));

refresh(): sync.onNext(importFromDb());