Hi am trying to run following kotlin code:
Code Snippet 1
This is not working
with the error:
function 'delay' should be called only from a coroutine or another suspend function
package kotlinx.coroutines.guide.exampleBasic02
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
launch {echoWorldWrapper() }
println("Hello")
}
suspend fun echoWorldWrapper() {
echoWorld()
}
fun echoWorld() {
delay(1000L)
println("World!")
}
However following works: Code Snippet 2:
package kotlinx.coroutines.guide.exampleBasic02
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
launch {echoWorldWrapper() }
println("Hello")
}
suspend fun echoWorldWrapper() {
delay(1000L)
println("World!")
}
In my production code I can only follow Code Snippet 1. Is there any workaround for approach 1 to work. I am new to Kotlin and couldn't find any other answer to this question. Thanks.
CodePudding user response:
It is not possible to call a suspend function from a function that is not also a suspend function. suspend
carries with it under the hood the state of a coroutine in a Continuation object. delay()
cannot operate without that coroutine to work with.
The functionality of delay()
is to suspend a coroutine for a period of time and then resume it. It doesn't make any sense for it to be called from a non-suspend function, because that means there is no coroutine to suspend.
The alternative for a non-suspend function is to use Thread.sleep()
, which will block the thread for a period of time. Example:
//Use withContext to make it acceptable to call a blocking function in a coroutine
suspend fun echoWorldWrapper() = withContext(Dispatchers.IO) {
echoWorld()
}
// A blocking function:
fun echoWorld() {
Thread.sleep(1000L)
println("World!")
}