2015-05-12 99 views
3

我學會了it is undesirable在反應式編程中使用Subjects,儘管我發現它們非常方便。但我知道他們可能會被濫用。所以我試圖創建一個無限Observable<ImmutableMap<Integer,ActionProfile>,每調用一次refresh()就需要發佈一個新的ImmutableMap。我也有一個forKey()方法返回Observable檢索最新的ActionProfile匹配一個特定的鍵。RxJava-無法訪問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 
    } 
} 
+0

我沒有足夠的經驗給主管回答你的問題,但:1)你會發現這個答案,我對CR有趣的問題:HTTP ://codereview.stackexchange.com/a/90090/68342 2.)你可能想看看源代碼sqlbrite,特別是這個文件,它在內部使用'Subject'來處理重載/觸發器:https:// github。 com/square/sqlbrite/blob/master/sqlbrite/src/main/java/com/squareup/sqlbrite/SqlBrite.java –

回答

3

冷觀測量通常在一時刻一個用戶互動,即使你訂閱更多的給他們,他們獨立運行,並不真正需要知道對方的存在。

另一方面,受試者不得不跟蹤他們自己收到的多播事件時的用戶。

快速查看您的代碼表明有一些競爭條件和丟失通知的可能性。而不是它,你可以依靠BehaviorSubject這是異步詞的'反應屬性'。讓它存儲當前不可變的映射和處理用戶:

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

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

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

我懷疑競爭條件的可能性。那麼爲什麼人們經常說科目幾乎不應該被使用?對於我的目的和你所展示的,在某些情況下它們似乎是合適的。 – tmn

+1

這樣的「不要用」陳述總覺得對我很苛刻。我想說,你應該首先尋找其他方法,但是有一些使用期望,這意味着幾乎立即使用主題。 – akarnokd