RxJava - 获取一个列表,对其项目进行操作,再次分组到列表中。 toList()等待onCompleted()

时间:2016-05-29 08:47:23

标签: android realm rx-java

我希望每次出现时都从我的数据库中获取所有未同步的项目,尝试将它们同步到后端,然后写入数据库,它们是同步的。为了执行此操作,我创建了这个操作链(使用RxJava observables):

  1. 每当发生数据库表的更改时,请获取非同步项目列表。
  2. 对于列表中的每个项目 - 将其发送到后端。
  3. 收集所有成功发送到后端的项目......
  4. ...并在一次交易中将它们写入数据库。
  5. 我试过这样的事情:

    newMsgsObservable //from realm database
                .flatMapIterable(new Func1<List<Message>, Iterable<Message>>() { //1
                    @Override
                    public Iterable<Message> call(List<Message> messages) {
                        return messages;
                    }
                })
                .flatMap(new Func1<Message, Observable<Message>>() { //2
                    @Override
                    public Observable<Message> call(Message message) {
                        return restService.sendMessage(message);
                    }
                })
                .toList() //3
                .flatMap(new Func1<List<Message>, Observable<?>>() { //4
                    @Override
                    public Observable<?> call(List<Message> messages) {
                        for(Message message : messages) {
                            message.setSynchronised(true);
                        }
                        persistence.saveMessages(messages);
                        return null; //yeah, I know, don't bother ;)
                    }
                })
                .subscribe();
    

    问题

    newMsgsObservable总是在等待数据库中的新变化(它永远不会完成)这是好的。不幸的是,toList()在再次返回项目列表之前等待complete的观察。我想要一个从数据库中获取单个列表的解决方案,对列表中的每个项执行所有操作,然后获取相同的列表并将其返回到下一个observable。并且每次从最初的可观察者中获得新列表时都会这样做。

    或许我做错了,我应该以另一种方式解决这个问题?

1 个答案:

答案 0 :(得分:4)

主要想法是将您的toList()移到另一个级别。因此,您的代码看起来像这样:

newMsgsObservable.flatMap(new Func1<List<Message>, Observable<List<Message>>>() {
    @Override
    public Observable<List<Message>> call(List<Message> messages) {
        return Observable.from(messages).flatMap(new Func1<Message, Observable<Message>>() {
            @Override
            public Observable<Message> call(Message message) {
                return restService.sendMessage(message);
            }
        }).toList();
    }
})
        .doOnNext(new Action1<List<Message>>() {
            @Override
            public void call(List<Message> messages) {
                for (Message message : messages) {
                    message.setSynchronised(true);
                }
                persistence.saveMessages(messages);
            }
        })
        .subscribe();