我正在使用RxJava以及concat()
和first()
运算符:
public Observable<List<Entity>> getEntities() {
invalidateCacheIfNeeded();
return Observable
.concat(cachedEntities(), networkEntities())
.first();
}
cachedEntities
返回从缓存列表构建的Observable,而networkEntities
方法使用Retrofit获取实体。
除非两个用户快速订阅getEntities()
返回的可观察量,否则这很有用。我猜第一次订阅的网络请求在第二次订阅时没有完成。在这种情况下,执行两个网络请求。我想避免的。
我尝试创建一个单线程调度程序,因此第二次调用的执行仅在第一次调用结束但没有运气时执行:
mSingleThreadScheduler = Schedulers.from(Executors.newSingleThreadExecutor());
和
public Observable<List<Entity>> getEntities() {
invalidateCacheIfNeeded();
return Observable
.concat(cachedEntities(), networkEntities())
.subscribeOn(mSingleThreadScheduler)
.first();
}
我已经尝试在Observable链中下调subscribeOn
调用,但我得到了相同的结果。
任何提示?
答案 0 :(得分:1)
我认为使方法线程安全不是一个好主意。因为它阻止了整个方法,从而降低了性能。因此建议使数据结构具有线程安全性。 在您的情况下,您在方法中使用列表
var array = [{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
],
result = array.reduce((p,c) => p[c.name] ? p : (p[c.name] = true, p.push(c.name), p), []);
console.log(result);
}
使用 CopyOnWriteArrayList 代替列表。它是线程安全的。
public Observable<List<Entity>> getEntities() {
}
希望它能奏效。
答案 1 :(得分:0)
这似乎是一个具有多个订阅者的可观察对象的相对常见的用例。你需要像
这样的东西public Observable<List<Entity>> getEntities() {
invalidateCacheIfNeeded();
return Observable
.concat(cachedEntities(), networkEntities())
.first()
.replay(1)
}
查看this question的答案 更深入的解释。
答案 2 :(得分:0)
鉴于
public Observable<List<Entity>> getEntities() {
invalidateCacheIfNeeded();
return Observable
.concat(cachedEntities(), networkEntities())
.first();
}
您应该创建AsyncSubject<Data> mSubject
并按照以下方式使用
private Observable<List<Entity>> networkEntities() {
return mSubject
.map(Data::getEntities);
}
您的网络通话应该如下所示
public Observable<Data> getDataFromNetwork() {
return networkOperation()
.subscribeOn(mSingleThreadScheduler)
.subscribe(mSubject);
}