How to Call Suspend Function from Function
Asked Answered
G

4

6

I am trying to call a suspend function in the parameters of another suspend function. The compiler doesn't actually allow this. It is telling me that a suspend function must be called from a suspend function or coroutine.

suspend fun compareElements(
    isReady: Boolean = isReady() // IDE complains.
) {
   ...
}

//This is for this questions purpose. Reality is a bit more complex.
suspend fun isReady() = true

How can I do this? I need to have isReady() in the parameter.

Gastrovascular answered 22/12, 2019 at 6:1 Comment(0)
R
10

You can pass a suspend function instead as a default parameter:

suspend fun compareElements(
    readyCheck: suspend () -> Boolean = { isReady() }
) {
    if (readyCheck()) {
        ...
    }
}
Rosser answered 22/12, 2019 at 6:25 Comment(0)
H
2

As another workaround:

suspend fun compareElements(
    isReady: Boolean? = null
) {
   val isReady0 = isReady ?: isReady()
   ...
}
Hittel answered 22/12, 2019 at 17:8 Comment(0)
D
0

I don't think the compiler is complaining about you trying to call a suspend function from another suspend function.

The real reason for the Error is that you are trying to call a suspend function as a default parameter value. Which is not supported by Kotlin and it should not be as well.

Default parameters are supposed to be values that are available when no other values are provided. If a function is being used as the default value, it has better chances of slowing down the execution when such function is called without any parameter in comparison with function call with a parameter value provided.

I would suggest that you use a simple constant value as a default parameter rather than a function call, much less a suspend function call.

If you really need to use the isReady function, then get the value from it inside the function compareElements and then use it.

Dowland answered 22/12, 2019 at 6:15 Comment(0)
R
0

Basically, coroutines are computations that can be suspended without blocking a thread. To continue the analogy, await() can be a suspending function (hence also callable from within an async {} block) that suspends a coroutine until some computation is done and returns its result:

async { // Here I call it the outer async coroutine
    ...
    // Here I call computation the inner coroutine
    val result = computation.await()
    ...
}

We see await is called on computation, so it might be async that returns Deferred, which means it can start another coroutine

fun computation(): Deferred<Boolean> {
    return async {
        true
    }
}

Does suspend mean that while outer async coroutine is waiting (await) for the inner computation coroutine to finish, it (the outer async coroutine) idles (hence the name suspend) and returns thread to the thread pool, and when the child computation coroutine finishes, it (the outer async coroutine) wakes up, takes another thread from the pool and continues? The thread is returned to the pool while the coroutine is waiting, and when the waiting is done, the coroutine resumes on a free thread in the pool.

Respectively answered 22/12, 2019 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.