Home > database >  cancelling a suspend function in kotlin if the same function is called again
cancelling a suspend function in kotlin if the same function is called again

Time:07-13

I want to cancel the function i created which simply increments a counter value. For example, if the specific function is triggered by click, I only want to display the log for the last uninterrupted click within 2 seconds. Basically, i want the function to cancel itself if called again if its ongoing (delay is ongoing). Is there such thing in kotlin?

val counter = mutableStateOf(0)
suspend fun addCounter(){
    counter.value  
    
   
    delay(2000)
    Log.e("click cat","click $counter")
}`

CodePudding user response:

Suspend function is a function that could be started, paused, and resume. Suspend functions are only allowed to be called from a coroutine or another suspend function and you can not cancel it in this way. Coroutine structured concurrency is the thing that you're looking for. You can use a Job to perform your task above. Now you can cancel the job anytime you need.

CodePudding user response:

This kind of event processing is usually handled using reactive streams and is often named the debounce operator. It exists in both ReactiveX (Debounce) and in Kotlin flows (debounce()).

As you already use coroutines, I suggest going with Kotlin flows. Please see the example below:

private val flow = MutableStateFlow(0)

suspend fun main() = coroutineScope {
    launch {
        // consumer of events
        flow
            .debounce(2.seconds)
            .collect { println(it) }
    }

    // producer
    delay(100)
    addCounter() // 1
    delay(500)
    addCounter() // 2, ignore 1
    delay(500)
    addCounter() // 3, ignore 2
    delay(2500) // show 3
    addCounter() // 4
    delay(500)
    addCounter() // 5, ignore 4
    delay(3000) // show 5
}

fun addCounter() {
    flow.value  
}

It shows only 3 and 5, because all other events were "cancelled" by subsequent events that came too fast.

  • Related