0
我已經寫了一個小測試來重現我的問題。我想嵌套緩存的observables,並且反映對ORIGINAL對象所做的底層數據結構所做的所有更改,但嵌套緩存似乎失敗了。更新緩存的rx java observables數據(使用嵌套緩存!)
是否可以解決問題?我已經寫了什麼,我期待下的問題...
測試
public static void test()
{
// --------------------
// TEST 1 - simple caching
// --------------------
List<Data> emptyData1 = getEmptyData()
.toBlocking()
.single();
L.d("TEST 1a - Size: %d == %d", emptyData1.size(), 0);
// add 1 empty data
emptyData1.add(new Data(0, false));
L.d("TEST 1b - Size: %d == %d (Loaded: %b)", emptyData1.size(), 1, emptyData1.get(0).loaded);
List<Data> emptyData2 = getEmptyData()
.toBlocking()
.single();
L.d("TEST 1c - Size: %d == %d (Loaded: %b)", emptyData2.size(), 1, emptyData2.get(0).loaded);
// --------------------
// TEST 2 - nested caching
// --------------------
List<Data> loadedData1 = getLoadedData()
.toBlocking()
.single();
L.d("TEST 2a - Size: %d == %d (Loaded: %b)", loadedData1.size(), 1, loadedData1.get(0).loaded);
// add a second data, this time we add a loaded data
loadedData1.add(new Data(1, true));
List<Data> loadedData2 = getLoadedData()
.toBlocking()
.single();
L.d("TEST 2b - Size: %d == %d (Loaded: %b, %b)", loadedData1.size(), 2, loadedData2.get(0).loaded, loadedData2.get(1).loaded);
// --------------------
// TEST 3 - test if empty observable is holding the loaded data as well now
// --------------------
List<Data> testEmptyStateData = getEmptyData()
.toBlocking()
.single();
L.d("TEST 3a - Size: %d == %d", testEmptyStateData.size(), 2);
// I don't expect this, but this will happen
if (testEmptyStateData.size() == 1)
{
L.d("TEST 3b1 - Size: %d == %d (Loaded: %b)", testEmptyStateData.size(), 2, testEmptyStateData.get(0).loaded);
}
// I expect this, but it won't be true
if (testEmptyStateData.size() == 2)
{
L.d("TEST 3b - Size: %d == %d (Loaded: %b, %b)", testEmptyStateData.size(), 2, testEmptyStateData.get(0).loaded, testEmptyStateData.get(1).loaded);
}
}
結果
TEST 1a - Size: 0 == 0
TEST 1b - Size: 1 == 1 (Loaded: false)
TEST 1c - Size: 1 == 1 (Loaded: false)
TEST 2a - Size: 1 == 1 (Loaded: true)
TEST 2b - Size: 2 == 2 (Loaded: true, true)
TEST 3a - Size: 1 == 2 // <= UNDESIRED RESULT!!!
TEST 3b1 - Size: 1 == 2 (Loaded: true) // <= at least the object in the list is correct! But I would expect that the empty observalbe would hold 2 items, both loaded! "Test 3b2" should be printed instead
問題
我希望所有的觀測將只將原始列表傳遞給用戶我總是得到原始對象,並且對該對象所做的所有更改都將反映在基本列表中,因此最後,空的可觀察對象應該返回2個加載的數據項,但對於此嵌套緩存方案並不適用。
我需要什麼
- 每個操作應該只運行一次!無論是否有人訂閱了可觀察的內容!這是whyI決定使用
cache()
- 可觀必須是共享的,必須重用
代碼
輔助功能和數據
private static Observable<List<Data>> mEmptyObservable = null;
private static Observable<List<Data>> mLoadedObservable = null;
public static Observable<List<Data>> getEmptyData()
{
if (mEmptyObservable == null)
{
// simple test data
List<Data> values = new ArrayList<>();
mEmptyObservable = Observable.just(values)
// cache and share observable
.cache().replay().refCount();
}
return mEmptyObservable;
}
public static Observable<List<Data>> getLoadedData()
{
if (mLoadedObservable == null)
{
mLoadedObservable = getEmptyData()
.flatMap(new Func1<List<Data>, Observable<Data>>()
{
@Override
public Observable<Data> call(List<Data> datas)
{
return Observable.from(datas);
}
})
.map(new Func1<Data, Data>()
{
@Override
public Data call(Data data)
{
data.load();
return data;
}
})
.toList()
// cache and share observable
.cache().replay().refCount();
}
return mLoadedObservable;
}
數據類
static class Data
{
int index;
boolean loaded;
public Data(int index, boolean processed)
{
this.index = index;
this.loaded = processed;
}
public void load()
{
if (!loaded)
{
// do some have operation... once only per data!
}
loaded = true;
}
}
我現在讀的鏈接,它看起來像'重播()。AUTOCONNECT()'可能是什麼,我需要一個solutuion(我需要緩存,我想每個步驟只需執行一次+我需要共享可觀察數據),但這會導致與我發佈的解決方案相同的結果。您的建議將不會執行並且已經在第一次調用getEmptyData()時阻塞。根據你的建議,我試着使用'share().replay()。autoConnect()'進行緩存和共享(這就是你想表達的想法),但是這又產生了與我發佈的解決方案相同的結果。 – prom85
你對包含'autoConnect'是正確的。儘管如此,您仍然可能會遇到訂購問題。你嘗試過'share()。autoConnect().replay()'? – JohnWowUs
'share()'不返回'ConnectableObserver' ...所以不行,因爲這是不可能的。我嘗試了我能想到的所有事情,大部分時間我都能得到相同的結果......只有我能想到的解決方案是處理緩存的自定義數據結構(我過去已經使用了類似的東西),但我認爲這應該沒有必要... – prom85