Andrew Todd
Andrew Todd

Reputation: 31

Dealing with suspend and non-suspend in Kotlin function parameters

I am fairly new to Kotlin, and am getting to grips with it's implementation of co-routines. I understand that any function that we may want Kotlin to deal with in a non-blocking way needs to be annotated with suspend, and that such functions can only be executed within a co-routine (or within another suspend function). So far so good.

However I keep coming across a problem with utility functions that accept other functions as parameters. For instance with arrow's Try:

suspend fun somethingAsync() = 1 + 1

Try { 1 + 1 } // All is well
Try { somethingAsync() } // Uh oh....

As the parameter to Try's invoke function/operator is not annotated with suspend, the second call will be rejected by the compiler. How does someone deal with this when writing utility functions that can not know if the code inside the passed function or lambda requires suspend or not? Writing a suspend and a non-suspend version of every such function seems incredibly tedious. Have I missed an obvious way to deal with this situation?

Upvotes: 3

Views: 1743

Answers (1)

Alexey Soshin
Alexey Soshin

Reputation: 17731

First, let's deal with suspend. What it means is this particular function blocks. Not that this function is asynchronous.
Usually, blocking means IO, but not always. In your example, the function doesn't block, nor does it something in an asynchronous manner (hence Async suffix is incorrect there). But lets assume actual utility code does block for some reason.

Now dealing with suspending functions is something that is done on the caller side. Meaning, what would you like to do while this is being executed:

fun doSomething() {
    Try { somethingAsync() }
}

If you're fine with doSomething to block, then you can use runBlocking:

fun doSomething() = runBlocking {
    Try { somethingAsync() }
}

Upvotes: 2

Related Questions