Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I call kotlin suspend function under lambda function

Let me start with example code snippets

suspend fun executeLive(result: MutableLiveData<Person>) {

    val response = ... //suspend api request

    mediatorLiveData.removeSource(response)

    mediatorLiveData.addSource(response) {
        result.value = sortData(it) // sortData is also suspend function which sortData at Dispatcher.Default
    }

}

In this example, sortData can't call under lambda function(in this case addSource).And also I already declare executeLive as suspend, that why suspend api request can start at first. But sortData function show compile time error

Suspend function can only be called from a coroutine body

So how do I change my code structure to solve this problems?

Update: Is there any article about this?

like image 993
amlwin Avatar asked Jan 21 '20 08:01

amlwin


People also ask

How does Kotlin handle suspend function?

We just have to use the suspend keyword. Note: Suspend functions are only allowed to be called from a coroutine or another suspend function. You can see that the async function which includes the keyword suspend. So, in order to use that, we need to make our function suspend too.

Can coroutines in Kotlin be suspended and resumed mid execution?

Coroutines can suspend themselves, and the dispatcher is responsible for resuming them. To specify where the coroutines should run, Kotlin provides three dispatchers that you can use: Dispatchers. Main - Use this dispatcher to run a coroutine on the main Android thread.

Can we call suspend function from Java?

Java Thread suspend() method This method is used if you want to stop the thread execution and start it again when a certain event occurs. This method allows a thread to temporarily cease execution. The suspended thread can be resumed using the resume() method.


1 Answers

A lambda is generally a callback function. Callback functions are so called because we wrap a block of code in a function, and pass it to someone else (or some place else) to be executed. It is a basic inversion of control where the code is not for you to execute, but someone else to do it (example the framework).

For example when you set a onClickListener on a button, we don't know when it will get called, we pass a lambda for the framework which takes care of the user interaction to call the specified action.

In your case similarly the suspend function is not calling the sortdata, it is passing it to the mediatorLiveData object to call it in its own context. It is not necessary the lambda you passed would be called from a coroutine body, as such this is not allowed.

like image 134
Mohammed Aquib Azad Avatar answered Sep 19 '22 12:09

Mohammed Aquib Azad