如何使用RxJava从Realm获取对象列表的Observable?

时间:2017-10-09 22:21:27

标签: realm rx-java observable rx-java2

我只有这个:

public Observable<List<Movie>> getAll() {
    return Observable.just(Movie.class)
            .flatMap(t -> Observable.just(t)
                    .doOnSubscribe(disposable -> realm.executeTransaction(realm1 -> realm1.where(Movie.class).findAll()))
                    .onErrorResumeNext((ObservableSource<? extends Class<Movie>>) observer -> Observable.empty())
                    .map(all -> realm.where(Movie.class).findAll())
            );
}

但它看起来真的很难看))

如果有可能避免重复代码并保存realm.where(Movie.class).findAll()并在map()中重用,那么一切都会好的。不推荐使用RealmResults方法addAll。

2 个答案:

答案 0 :(得分:0)

同样描述here

private io.reactivex.Flowable<List<Movie>> getAll() {
    return io.reactivex.Flowable.create(new FlowableOnSubscribe<List<Movie>>() {
        @Override
        public void subscribe(FlowableEmitter<List<Movie>> emitter)
                throws Exception {
            Realm realm = Realm.getDefaultInstance();
            RealmResults<Movie> results = realm.where(Movie.class).findAllAsync();
            final RealmChangeListener<RealmResults<Movie>> listener = _realm -> {
                if(!emitter.isUnsubscribed() && results.isLoaded()) {
                     emitter.onNext(results);
                }
            };
            emitter.setDisposable(Disposables.fromRunnable(() -> {
                results.removeChangeListener(listener);
                realm.close();
            }));
            results.addChangeListener(listener);
        }
    }, BackpressureStrategy.LATEST)
    .subscribeOn(AndroidSchedulers.mainThread())
    .unsubscribeOn(AndroidSchedulers.mainThread());

但正如@masp所说的那样,你可以在my article about this on realm.io that was published a month ago中阅读更多关于使用Realm和RxJava2设计反应数据层的信息。

因此,对于Realm 4.0.0-RC1及更高版本,您实际上可以做到

private io.reactivex.Flowable<List<Movie>> getAll(Realm realm) {
    if(realm.isAutoRefresh()) {
        return realm.where(Movie.class)
                .findAllAsync()
                .asFlowable()
                .filter(RealmResults::isLoaded);
    } else { // for background threads
        return Flowable.just(realm.where(Movie.class).findAll());
    }
}

答案 1 :(得分:0)

您始终可以在另一种方法中提取查找电影的代码以供重复使用。即使在功能API中,我们也应该避免破坏DRY。

public void code() {
    public Observable<List<Movie>> getAll () {
        return Observable.just(Movie.class)
                .flatMap(t -> Observable.just(t)
                        .doOnSubscribe(disposable -> realm.executeTransaction(realm1 -> findMovie((Object) realm1)))
                        .onErrorResumeNext((ObservableSource<? extends Class<Movie>>) observer -> Observable.empty())
                        .map(all -> findMovie((Object) all))
                );
    }

}

private Object findMovie(Object realm1) {
    return realm1.where(Movie.class).findAll();
}