Rxjava - 如何正确检查 Maybe/Observable 是否为空?

Rxjava - How to check if Maybe/Observable is empty properly?

我正在使用 Maybe 访问数据库,我的目标是在 Maybe 完成时调用网络,表明数据库中没有数据(我正在使用房间)。我有以下功能:

@Override
public Observable<List<Item>> getResults() {
    return getResultsFromDatabase().toObservable().switchIfEmpty(getResultsFromNetwork());
}

@Override
public Observable<List<Item>> getResultsFromNetwork() {
    System.out.println("getting results from network");
    return api.getData().doOnNext(new Consumer<List<Item>>() {
        @Override
        public void accept(List<Item> items) throws Exception {
            itemDao.insert(items);
        }
    });
}

@Override
public Maybe<List<Item>> getResultsFromDatabase() {
    System.out.println("getting coins from database");
    return itemDao.getAllItems();
}

然而,switchIfEmpty 的工作有点出乎意料,因为它总是被调用,即使数据库中有对象。

return getResultsFromDatabase().toObservable().switchIfEmpty(getResultsFromNetwork());
  1. 是否可以仅使用 toObservable() 将 Maybe 转换为 Observable?
  2. 是否有另一种方法来检查 Maybe 是否为空然后对其进行操作?

使用 Single 而不是 Maybe。因为当db中没有行时,Maybe会直接补全,不会调用error。但是当没有行时,Single 将导致 onErrorEmptyResultSetException。然后我们可以使用 Rx 的能力 return 来自网络调用的数据。方法如下:

首先将您的 itemDao.getAllItems() 更改为 return Single<List<Item>>。 然后将 getResultsFromDatabase() 更改为 return Single 以及:

@Override
public Single<List<Item>> getResultsFromDatabase() {
    System.out.println("getting coins from database");
    return itemDao.getAllItems();
}

现在您需要使用 onErrorResumeNext 以便 return 来自网络调用的数据,因此将 getResults() 更改为:

@Override
public Observable<List<Item>> getResults () {
            return getResultsFromDatabase()
                    .toObservable()
                    .onErrorResumeNext(new ObservableSource<List<Item>>() {
                        @Override
                        public void subscribe(io.reactivex.Observer<? super List<Item>> observer) {
                            getResultsFromNetwork();
                        }
                    });
        }

调用 getResultsFromNetwork 的原因不是您将其 return 值传递给 switchIfEmpty,而不是其引用吗?

我会把它改成例如

getResultsFromDatabase().toObservable().switchIfEmpty(Maybe.Callable(this::getResultsFromNetwork))

看看是否有帮助