I\'m reading Kotlin Coroutine and know that it is based on suspend
function. But what does suspend
mean?
Coroutine or function gets
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