Observable#take(Long) 没有在 RxJava 中返回所需的项目大小

Observable#take(Long) not returning desired size of items in RxJava

我正在使用 RxJava/Kotlin Observable#take() 从列表中获取前 50 项。但是 #take() 运算符的行为并不像 Rx 文档中那样。

在 Rx 文档中,#take() 定义为:

"Emit only the first n items emitted by an Observable"

我有这样的功能:

我们可以看到 pageSize 参数是 50

list 的初始 size300

在那之后 #take(50) 被应用到那个 Observable 并且在下一个断点我仍然得到 full size 列表 i.e. size = 300

但是 just for the check,如果调试器或可观察对象出现问题,我尝试只获取 displayName 包含“9”的项目,但这次我得到了 smaller list 的预期结果9 在每个 #displayName field.

我相信 RxJava/Kotlin's #take() 运营商没那么疯狂,我就是这样。

好好看看你的方法的 return 类型 - Single<List<FollowersEntity>>。从 remoteFollowersService.getFollowers() 编辑的 Observable return 是 而不是 一个发出 300 FollowersEntity 项的 Observable - 它是一个发出 单个 项的 Observable,并且该单个项是包含 300 个 FollowersEntity 项的 List。换句话说,您需要在列表上调用 take,而不是在可观察对象上调用。

    return remoteFollowersService.getFollowers()
        .map { val size = it.size; it } // for debugging
        .map { it.take(pageSize) }
        .map { val size = it.size; it } // for debugging
        .map { it.filter { item -> item.displayName.contains("9") } }
        .single(emptyList())

take 行为正确,因为它只会给你 50 List<FollowersEntry> "marbles"。根据您的屏幕截图和措辞,我猜您想要 50 FollowersEntry。对象容器和对象本身之间存在根本的逻辑差异。 RxJava 只能看到类型为 List<> 的对象序列,但它无法了解您打算使用的嵌套对象。

因此,您要么必须在 map 中使用 it.take(50)(或任何 Kotlin 集合函数),要么通过 flatMapIterable 将列表序列展开为条目序列:

getFollowers()
.flatMapIterable(entry -> entry)
.take(50 /* entries this time, not lists */)