情况是这样的:
我有领域层为业务逻辑提供数据抓取接口,并且我有2个数据源:本地数据库和远程网络。
它是这样工作的:
请求所有用户:DataRepository.getInstance().getUsers();
在DataRepository中,有两个来源:LocalDataSource.getUsers()从本地数据库提取所有用户,如果没有数据,则忽略此请求。
RemoteDataSource.getUsers()请求我们服务器上的最新用户列表(即使本地数据库中有数据,为了保持数据更新),当请求数据时,将其保存或更新到本地数据库并发回结果。
我知道我可以通过在DataRepository中执行此操作来实现我的目标:
public Observable> getUsers() {
return Observable.create(new Observable.OnSubscribe>() {
@Override
public void call(Subscriber super List> subscriber) {
// 1. Request users from local database
List localUsers = mLocalDataSource.getUsers();
if (!localUsers.isEmpty()) {
subscriber.onNext(localUsers);
}
// 2. Request the latest user list from server
// Send a retrofit2 request
Call> call = mRemoteDataSource.getUsers();
try {
List networkUsers = call.execute().body();
mLocalDataSource.saveUsers(networkUsers);
subscriber.onNext(networkUsers);
subscriber.onCompleted();
} catch (IOException e) {
subscriber.onError(e);
}
}
});
}现在认为我已经在项目中使用了rxjava,为什么不使用SqlBrite和Retrofit2 RxAdapters来实现这个更方便?
因此LocalDataSource.getUsers()现在返回Observable>,RemoteDataSource.getUsers()也返回。
LocalDataSource.java
public Observable getUsers() {
final String sqlQuery = String.format("SELECT * FROM %s", UserTable.TABLE_NAME);
return mDatabaseHelper.createQuery(UserTable.TABLE_NAME, sqlQuery)
.mapToList(new Func1() {
@Override
public User call(Cursor c) {
return UserTable.parseCursor(c);
}
});
}RemoteDataSource.java
public Observable> getUsers() {
return mRetrofitApi.users();
}题:
我应该在DataRepository.getUsers()上做些什么来达到与旧技巧相同的目的?
public Observable> getUsers() {
Observable> localUsers = mLocalDataSource.getUsers();
Observable> remoteUsers = mRemoteDataSource.getUsers()
.flatMap(new Func1, Observable>() {
@Override
public Observable call(List users) {
return Observable.from(users);
}
})
.doOnNext(new Action1() {
@Override
public void call(User user) {
mLocalDataSource.saveUser(user);
}
})
.toList();
// What should I return to make two observables both able to emit results to the Subscriber
return Observable.concat(localUsers, remoteUsers); // ???
}