how to break from lambda passed to recursive function when provided condition met

后端 未结 2 1307
时光取名叫无心
时光取名叫无心 2021-01-28 11:50

I am writing a custom loop dsl and I want it\'s usage to look like below


    var counter1 = 0
    var counter2 = 0
    loop {
            counter1          


        
2条回答
  •  甜味超标
    2021-01-28 12:34

    I didn't understand much about the function delayedResult, because none of the dsl's public functions return a result. However, I come up with an solution for cancelling the loop.

    As far as I understood, we have to have a loop that doesn't block the current thread. Therefore, it must be run in a coroutine, but in order to be able to cancel the loop, the dsl must run its own coroutine. This inner coroutine is run using coroutineScope, so it suspends the parent coroutine until it's finished or cancelled.

    @ExperimentalTime
    class Loop {
        private val loopInterval = 1.seconds
    
        suspend fun loop(block: suspend () -> Unit) = loop(loopInterval, block)
    
        suspend fun loop(minimumInterval: Duration, block: suspend () -> Unit):Job  = coroutineScope {
            launch {
                while (true) {
                    block()
                    delay(minOf(minimumInterval, loopInterval).toLongMilliseconds())
                }
            }
        }
    
        suspend fun stopIf(condition: Boolean) = coroutineScope {
            suspendCancellableCoroutine {
                if (condition) it.cancel() else it.resumeWith(Result.success(Unit))
            }
        }
    }
    
    @ExperimentalTime
    suspend fun loop(block: suspend Loop.() -> Unit):Job {
        return Loop().run {
            this.loop {
                block(this)
            }
        }
    }
    

提交回复
热议问题