【发布时间】:2021-07-29 15:01:53
【问题描述】:
我有一个服务可以获取用户的所有朋友,它应该过滤掉被用户阻止或阻止用户的用户。
这是我目前的方法。有两个存储库。
友情信息:
interface FriendshipRepository : CoroutineCrudRepository<Friendship, Long> {
fun findByUserId(userId: Long): Flow<Friendship>
}
还有一个用于块信息:
interface BlockRepository : CoroutineCrudRepository<Block, Long> {
fun findByUserIdAndFriendIdIn(userId: Long, friendId: Set<Long>): Flow<Block>
fun findByUserIdInAndFriendId(userId: Set<Long>, friendId: Long): Flow<Block>
}
问题
我有两个问题。
- 在查询
blockRepository之前,我需要阻止收集朋友ID。 - 我不知道如何过滤原始流而不阻塞blockRepository的结果,因为我需要知道所有块。
此实现有效 - 由于 asFlux 和 block()!! 操作,我觉得它看起来很奇怪,但我想不出更好的解决方案:
override suspend fun findFriendIdsByUserId(userId: Long): Flow<Long> {
val friends = friendshipRepository.findByUserId(userId)
.filter { it.status == FRIEND }
.map { it.friendId }
.asFlux()
.collectList()
.block()!!
.toMutableSet()
val userBlocks = blockRepository.findByUserIdAndFriendIdIn(userId, friends)
val userIsBlockedBy = blockRepository.findByUserIdInAndFriendId(friends, userId)
val blocks = userBlocks.asFlux().mergeWith(userIsBlockedBy.asFlux())
.map { it.friendId }
.collectList()
.block()!!
.toSet()
friends.removeAll(blocks)
return friends.asFlow()
}
有更好的方法吗?
【问题讨论】:
-
为什么
findByUserId会返回一个流?它实际上是返回可观察数据还是只是一个包装器? -
另一个控制器/服务使用相同的方法向前端提供好友列表(包括被屏蔽的好友)。它更像是一个包装器,但我认为让它返回 Set 会与使用反应弹簧堆栈相矛盾。
-
@Stuck 只是出于好奇,如果您已经有了流,为什么还要到处使用
.asFlux()而不是使用Flows? -
@Joffrey:因为流没有合并运算符。但我很乐意让它们保持流动!
-
嗯,merge(vararg Flow) 呢?
标签: kotlin spring-webflux kotlin-coroutines