有很多方法可以使RxJava实现惰性分页。如果你仔细想想,最简单的加载分页数据的方法就是加载所有东西,然后取我们需要的任何数据。这听起来很傻,但由于惰性,这是可行的。首先,我们生成所有可能的页码,然后我们请求分别加载每个页面:

Observable<List<Person>> allPages = Observable
    .range(0, Integer.MAX_VALUE)
    .map(this::listPeople)
    .takeWhile(list -> !list.isEmpty());

如果这不是RxJava,那么前面的代码将花费大量的时间和内存,基本上将整个数据库装载到内存中。但是由于Observable是惰性的,所以对数据库的查询还没有出现。此外,如果我们找到一个空的页面,它意味着之后的所有的页面都是空的(我们到达了表的末尾)。因此,我们使用takeWhile()而不是filter()。我们可以使用concatMap()在来使得allPages扁平化(参考75页的“Preserving Order Using concatMap()”)。

Observable<Person> people = allPages.concatMap(Observable::from);

concatMap()需要一个从List <Person >到 Observable<Person> 的转换函数,该函数为每个页面都执行。或者,我们也可以尝试concatMapIterable(),它做同样的事情,但是这个转换针对每一个上游的值,需要返回一个 Iterable<Person>:

Observable<Person> people = allPages.concatMapIterable(page -> page);

无论您选择哪种方法,所有针对Person对象的转换都是惰性的。只要您限制了要处理的记录的数量(例如,使用people.take(15)), Observable<Person>将尽可能晚地调用listPeople()。

results matching ""

    No results matching ""