使用RxJava在本地和服务器之间同步Recrods

时间:2015-05-27 07:32:07

标签: java rx-java

我正在尝试在本地记录和服务器上的记录之间同步一些数据。  syncList是与本地记录同步操作的入口点。在这个方法中,我调用一个方法syncResultObservable,它将返回带有服务器上记录的Observable对象。

下载服务器的记录后,我会使用flatmap通过调用map<String, List<String>>将同步结果转换为syncResult (List<String> local, List<String> server)。 结果map应该有2个键  "toAdd":List<String>  "toRemove":List<String>

现在,我想对每个结果执行单独的操作。 recordsAddObservable应该从toAdd键添加列表(我能够这样做)。 recordsRemoveObservable应该删除从toRemove键添加列表(找不到使用相同observable执行此操作的方法)。

recordsAddObservable操作toAdd记录对我来说很好。但是,我试图找到一种方法在地图结果上调用recordsRemoveObservable,而不会导致整个同步操作再次开始删除案例。 以下是添加&#39;添加&#39;的小片段。记录。

public void syncList(final List<String> localData) {
   //fetch the server data
    Observable<Map<String, List<String>>> syncResultObservable = serverDataDownloadObservable(userid)
            .flatMap(new Func1<String[], Observable<Map<String, List<String>>>>() {
                @Override
                public Observable<Map<String, List<String>>> call(String[] serverData) {
                    Map<String, List<String>> map = syncResult(localData, Arrays.asList(serverData));
                    return Observable.just(map);
                }
            });

    syncResultObservable.flatMap(new Func1<Map<String, List<String>>, Observable<List<String>>>() {
        @Override
        public Observable<List<String>> call(Map<String, List<String>> stringListMap) {
            List<String> toAdd;
            toAdd = stringListMap.get("toAdd");
            if (toAdd == null || toAdd.isEmpty()) {
                toAdd = new ArrayList<String>();
            }
            return Observable.just(toAdd);
        }
    }).flatMap(new Func1<List<String>, Observable<Result>>() {
        @Override
        public Observable<Result> call(List<String> strings) {
            if (strings.isEmpty() == false) {
                String[] toAdd = strings.toArray(new String[strings.size()]);
                Log.i(LogEnum.LogPriority.info, getClass, "syncRecords: will try to add records ", toAdd);
                return apis.recordsAddObservable(userid, toAdd);
            }
                Log.i("Tag", getClass, "syncRecords: no records to add, toAdd);

            Log.i("Tag", getClass, "syncRecords: no records need to be added ");
            return Observable.just(new Result(null, null));
        }
    }).subscribeOn(Schedulers.io()).subscribe(new Subscriber<Result>() {
        @Override
        public void onCompleted() {
             //
        }

        @Override
        public void onError(Throwable e) {
        }

        @Override
        public void onNext(Result result) {
            onCompleted();
        }
    });
}






public Map<String, List<String>> syncResult (List<String> local, List<String>  server) {
    . . .
    . . .

    Map<String, List<String>> map = new HashMap<>();
    map.put("toAdd", toAddList);
    map.put("toRemove", toRemoveList);
    return map
}

如果有一种简单的方法可以执行不同结果集的单独操作,请告诉我。

由于 大O

2 个答案:

答案 0 :(得分:1)

Here is一个可运行的例子,我认为,它可以做你想要的:

  • 获取本地值和服务器值的流
  • 在他们身上申请列表,
  • 将它们拼接在一起并应用差异计算逻辑
  • 由于您选择使用具有特定键的地图,我们需要将其展平为键控流
  • 然后根据两个键创建组
  • 并切换flatMap中的键以启动每个案例所需的异步工作。

答案 1 :(得分:1)

这就是我解决它的方法。

public void syncList(final List<String> localData) {
   //fetch the server data

         Observable<Map<String, List<String>>> syncResultObservable = serverDataDownloadObservable(userid)
        .flatMap(new Func1<String[], Observable<Map<String, List<String>>>>() {
            @Override
            public Observable<Map<String, List<String>>> call(String[] serverData) {
                Map<String, List<String>> map = syncResult(localData, Arrays.asList(serverData));
                return Observable.just(map);
            }
        }).subscribeOn(Schedulers.io())
            .subscribe(new Action1<Map<String, List<String>>>() {
                @Override
                public void call(Map<String, List<String>> stringListMap) {
                    List<String> toAdd = stringListMap.get("toAdd");
                    if (toAdd != null && toAdd.isEmpty() == false) {
                    } else {
                        addRecords(toAdd);
                    }
                    List<String> toRemove = stringListMap.get("toRemove");
                   if (toRemove != null && toRemove.isEmpty() == false) {
                        removeRecords(toRemove);
                    }
                }
            });

}