What does the suspend function mean in a Kotlin Coroutine?

前端 未结 7 2082
不知归路
不知归路 2020-11-27 10:19

I\'m reading Kotlin Coroutine and know that it is based on suspend function. But what does suspend mean?

Coroutine or function gets

相关标签:
7条回答
  • 2020-11-27 10:47

    I wanted to give you a simple example of the concept of continuation. This is what a suspend function does, it can freeze/suspend and then it continues/resumes. Stop thinking of coroutine in terms of threads and Semaphore. Think of it in terms of continuation and even callback hooks.

    To be clear, a coroutine can be paused by using a suspend function. lets investigate this:

    In android we could do this for example :

    var TAG = "myTAG:"
            fun myMethod() { // function A in image
                viewModelScope.launch(Dispatchers.Default) {
                    for (i in 10..15) {
                        if (i == 10) { //on first iteration, we will completely FREEZE this coroutine (just for loop here gets 'suspended`)
                            println("$TAG im a tired coroutine - let someone else print the numbers async. i'll suspend until your done")
                            freezePleaseIAmDoingHeavyWork()
                        } else
                            println("$TAG $i")
                        }
                }
    
                //this area is not suspended, you can continue doing work
            }
    
    
            suspend fun freezePleaseIAmDoingHeavyWork() { // function B in image
                withContext(Dispatchers.Default) {
                    async {
                        //pretend this is a big network call
                        for (i in 1..10) {
                            println("$TAG $i")
                            delay(1_000)//delay pauses coroutine, NOT the thread. use  Thread.sleep if you want to pause a thread. 
                        }
                        println("$TAG phwww finished printing those numbers async now im tired, thank you for freezing, you may resume")
                    }
                }
            }
    

    Above code prints the following :

    I: myTAG: my coroutine is frozen but i can carry on to do other things
    
    I: myTAG: im a tired coroutine - let someone else print the numbers async. i'll suspend until your done
    
    I: myTAG: 1
    I: myTAG: 2
    I: myTAG: 3
    I: myTAG: 4
    I: myTAG: 5
    I: myTAG: 6
    I: myTAG: 7
    I: myTAG: 8
    I: myTAG: 9
    I: myTAG: 10
    
    I: myTAG: phwww finished printing those numbers async now im tired, thank you for freezing, you may resume
    
    I: myTAG: 11
    I: myTAG: 12
    I: myTAG: 13
    I: myTAG: 14
    I: myTAG: 15
    

    imagine it working like this:

    So the current function you launched from does not stop, just a coroutine would suspend while it continues. The thread is not paused by running a suspend function.

    I think this site can help you straight things out and is my reference.

    Let's do something cool and freeze our suspend function in the middle of an iteration. We will resume it later in onResume

    Store a variable called continuation and we'll load it with the coroutines continuation object for us :

    var continuation: CancellableContinuation<String>? = null
    
    suspend fun freezeHere() = suspendCancellableCoroutine<String> {
                continuation = it
            }
    
     fun unFreeze() {
                continuation?.resume("im resuming") {}
            }
    

    Now, let's return to our suspended function and make it freeze in middle of iteration :

     suspend fun freezePleaseIAmDoingHeavyWork() {
            withContext(Dispatchers.Default) {
                async {
                    //pretend this is a big network call
                    for (i in 1..10) {
                        println("$TAG $i")
                        delay(1_000)
                        if(i == 3)
                            freezeHere() //dead pause, do not go any further
                    }
                }
            }
        }
    

    Then somewhere else like in onResume (for example):

    override fun onResume() {
            super.onResume()
            unFreeze()
        }
    

    And the loop will continue. Its pretty neat to know we can freeze a suspend function at any point and resume it after some time has beeb passed. You can also look into channels

    0 讨论(0)
提交回复
热议问题