Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin RxJava2&;改造:如何获取数据页_Kotlin_Retrofit_Rx Java - Fatal编程技术网

Kotlin RxJava2&;改造:如何获取数据页

Kotlin RxJava2&;改造:如何获取数据页,kotlin,retrofit,rx-java,Kotlin,Retrofit,Rx Java,目标:我想反复调用一个更新服务(GET),该服务返回分页数据,直到我用尽了它的页面。从第0页转到第n页 首先,我已经看过答案了。第一种方法确实有效,但我不太喜欢递归解决方案,因为它可能导致堆栈溢出。第二种方法在您尝试使用调度程序时失败 下面是第二个示例: Observable.range(0, 5/*Integer.MAX_VALUE*/) // generates page values .subscribeOn(Schedulers.io()) // need t

目标:我想反复调用一个更新服务(GET),该服务返回分页数据,直到我用尽了它的页面。从第0页转到第n页

首先,我已经看过答案了。第一种方法确实有效,但我不太喜欢递归解决方案,因为它可能导致堆栈溢出。第二种方法在您尝试使用调度程序时失败

下面是第二个示例:

Observable.range(0, 5/*Integer.MAX_VALUE*/) // generates page values
    .subscribeOn(Schedulers.io())           // need this to prevent UI hanging
    // gamesService uses Schedulers.io() by default
    .flatMapSingle { page -> gamesService.getGames(page) }
    .takeWhile { games -> games.isNotEmpty() } // games is a List<Game>
    .subscribe(
        { games -> db.insertAll(games) },
        { Logger.e(TAG, it, "Error getting daily games: ${it.message}") }
    )
在这里不使用
createWithScheduler()
确实不是一个选项

下面是我尝试过的另一个想法:

val atomic = AtomicInteger(0)
Observable.generate<Int> { it.onNext(atomic.getAndIncrement()) }
    .subscribeOn(Schedulers.io())
    .flatMapSingle { page -> gamesService.getGames(page) }
    .takeWhile { games -> games.isNotEmpty() }
    .subscribe(
        { games -> dailyGamesDao.insertAll(games) },
        { Logger.e(TAG, it, "Error getting daily games: ${it.message}") }
    )
val原子=原子整数(0)
Observable.generate{it.onNext(atomic.getAndIncrement())}
.subscribeOn(Schedulers.io())
.flatMapSingle{page->gamesService.getGames(page)}
.takeWhile{games->games.isNotEmpty()}
.订阅(
{games->dailyGamesDao.insertAll(games)},
{Logger.e(标记,it,“获取每日游戏时出错:${it.message}”)}
)
这是另一种情况,在我引入
调度器之前,它一直按预期工作。生成器生成的值太多,我希望它在
takeWhile
发现空列表时停止

我还尝试了各种各样的
concat
(concatWith、concatMap等)


在这一点上,我真的只是想找人帮我纠正(对他们来说)我对RxJava操作符明显存在的、完全基本的误解。

我找到了部分解决方案。(如果我找到“最终”解决方案,我可以在以后编辑此答案。)

tl;dr我应该将我的
单个
s转换为
可观察的
s,并使用
flatMap
重载,该重载采用
maxConcurrency
参数。例如:

Observable.range(0, SOME_SUFFICIENTLY_LARGE_NUMBER)
    .subscribeOn(Schedulers.io())
    .flatMap({ page -> gamesService.getGames(page).toObservable }, 1 /* maxConcurrency */)
    .takeWhile { games -> games.isNotEmpty() }
    .subscribe(
        { games -> dailyGamesDao.insertAll(games) },
        { Logger.e(TAG, it, "Error getting daily games: ${it.message}") }
    )
基本上就是这样。通过将并发线程的数量限制为1,我现在拥有了我所寻求的“一个接一个”行为。我唯一不喜欢的是,我想这是一个小小的抱怨,那就是我的基本
Observable.range()
仍然可以发出很多值——这比下游
单个
s/
Observable
s使用的要多

PS:我之前找不到这个解决方案的一个原因是我使用的是RXJava2.1.9。当我把它推到2.1.14时,我可以访问新的重载。哦,好吧

Observable.range(0, SOME_SUFFICIENTLY_LARGE_NUMBER)
    .subscribeOn(Schedulers.io())
    .flatMap({ page -> gamesService.getGames(page).toObservable }, 1 /* maxConcurrency */)
    .takeWhile { games -> games.isNotEmpty() }
    .subscribe(
        { games -> dailyGamesDao.insertAll(games) },
        { Logger.e(TAG, it, "Error getting daily games: ${it.message}") }
    )