簡體   English   中英

如何修改 Kotlin Flow distinctUntilChanged 添加過期時間

[英]How do I modify Kotlin Flow distinctUntilChanged to add an expiry time

我如何使用distinctUntilChanged()並向其添加到期時間,這意味着如果流中存在相同的值,我們仍會收集它,因為它比發出前一個重復值后的expiry毫秒數長。

flow { 
  emit("A")    // printed
  emit("B")    // printed
  emit("A")    // printed
  emit("A")    // NOT printed because duplicate
  delay(5000)
  emit("A")    // printed because 5 seconds elapsed which is more than expiry
}
  .distinctUntilChanged(expiry = 2000)
  .collect {
    println(it)
  }

我想這樣打印:

A
B
A
A

這是測試它的代碼:

  @Test
  fun `distinctUntilChanged works as expected`(): Unit = runBlocking {
    flow {
      emit("A")    // printed
      emit("B")    // printed
      emit("A")    // printed
      emit("A")    // NOT printed because duplicate
      delay(5000)
      emit("A")    // printed because 5 seconds elapsed which is more than expiry
    }
      .distinctUntilChanged(expiry = 2000)
      .toList().also {
        assertEquals("A", it[0])
        assertEquals("B", it[1])
        assertEquals("A", it[2])
        assertEquals("A", it[3])
      }
  }

我認為這會起作用,但我沒有進行太多測試。 我認為邏輯是不言自明的。 havePreviousValue存在的原因是萬一T可以為空並且第一個發出的值是null

fun <T> Flow<T>.distinctUntilChanged(expiry: Long) = flow {
    var havePreviousValue = false
    var previousValue: T? = null
    var previousTime: Long = 0
    collect {
        if (!havePreviousValue || previousValue != it || previousTime + expiry < System.currentTimeMillis()) {
            emit(it)
            havePreviousValue = true
            previousValue = it
            previousTime = System.currentTimeMillis()
        }
    }
}

另外一個選擇:

fun <T> Flow<T>.distinctUntilChanged(expiry: Long) = 
    merge(
        distinctUntilChanged(), 
        channelFlow {
            val shared = buffer(Channel.CONFLATED).produceIn(this)
            debounce(expiry).takeWhile { !shared.isClosedForReceive }.collect { 
                val lastVal = shared.receive()
                shared.receive().let { if(lastVal == it) send(it) }
            }
        }
    )

它基本上將非獨特值添加回 distinctUntilChanged()。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM