如何修改KotlinFlow distinctUntilChanged以添加过期时间

u3r8eeie  于 2022-11-25  发布在  Kotlin
关注(0)|答案(1)|浏览(200)

我如何使用distinctUntilChanged(),但也添加了一个过期,这意味着如果相同的值在流中,我们仍然收集它,因为它比expiry长毫秒后,前一个重复的值发出。

  1. flow {
  2. emit("A") // printed
  3. emit("B") // printed
  4. emit("A") // printed
  5. emit("A") // NOT printed because duplicate
  6. delay(5000)
  7. emit("A") // printed because 5 seconds elapsed which is more than expiry
  8. }
  9. .distinctUntilChanged(expiry = 2000)
  10. .collect {
  11. println(it)
  12. }

我希望打印以下内容:

  1. A
  2. B
  3. A
  4. A

下面是测试它的代码:

  1. @Test
  2. fun `distinctUntilChanged works as expected`(): Unit = runBlocking {
  3. flow {
  4. emit("A") // printed
  5. emit("B") // printed
  6. emit("A") // printed
  7. emit("A") // NOT printed because duplicate
  8. delay(5000)
  9. emit("A") // printed because 5 seconds elapsed which is more than expiry
  10. }
  11. .distinctUntilChanged(expiry = 2000)
  12. .toList().also {
  13. assertEquals("A", it[0])
  14. assertEquals("B", it[1])
  15. assertEquals("A", it[2])
  16. assertEquals("A", it[3])
  17. }
  18. }
4smxwvx5

4smxwvx51#

我认为这是可行的,但我没有做太多测试。我认为逻辑是不言自明的。havePreviousValue存在的原因是T是可空的,第一个发出的值是null

  1. fun <T> Flow<T>.distinctUntilChanged(expiry: Long) = flow {
  2. var havePreviousValue = false
  3. var previousValue: T? = null
  4. var previousTime: Long = 0
  5. collect {
  6. if (!havePreviousValue || previousValue != it || previousTime + expiry < System.currentTimeMillis()) {
  7. emit(it)
  8. havePreviousValue = true
  9. previousValue = it
  10. previousTime = System.currentTimeMillis()
  11. }
  12. }
  13. }

相关问题