Hi, I read that if I want two functions to run con...
# getting-started
n
Hi, I read that if I want two functions to run consecutively, they have to be suspend functions. So I turned
function1 ()
and
function2 ()
into suspend functions, and set them up like this:
Copy code
val scope = rememberCoroutineScope()

    ElevatedButton(
        onClick = {
            scope.launch {
                function1 ()
                function2 ()
            }
        },
The problem is that I need for function1 to be completed before function2 can start. So if I put a 1 second delay between the two, my app works as expected, but if I don't it seems function2 does not wait for function1 to complete before it starts. Is there a way to get f1 to finish before f2 starts without adding a delay in between the two?
c
Running
suspend
functions sequentially is how coroutines work by nature. A function marked
suspend
will run and “suspend execution” until it completes and that function returns. So in your example, until
function1()
returns,
function2()
will not start. But how those functions are internally implemented may affect that behavior. Just because a function is marked
suspend
doesn’t necessarily mean that it actually will suspend execution and wait for it to complete. For example, if each of those functions calls
launch { }
, then they will return immediately and be running in parallel instead of in series, even if the functions are marked suspend. Basically,
suspend
doesn’t do anything on its own to make sure things are running in series or in parallel, it just opens up the possibility for you to do that yourself. Can you paste the implementation of your
function1
and function2`? It’s difficult to know why it’s not behaving correctly without knowing how you have those functions implemented
n
Thanks for the explanation. So function1 looks like this:
Copy code
suspend fun interruptionFilterAll() {
        notificationManager.setInterruptionFilter(
            NotificationManager.INTERRUPTION_FILTER_ALL
        )
    }
and function2 is this:
Copy code
suspend fun interruptionFilterPriority() {
        notificationManager.setInterruptionFilter(
            NotificationManager.INTERRUPTION_FILTER_PRIORITY
        )
    }
I have a series of options that look like this:
Copy code
val option3 = Option(
        title = "PRIORITY ONLY",
        function = { scope.launch { filterFun.interruptionFilterPriority() } },
        icon = Icons.Filled.Star,
        selected = selected,
        enabled = enabled,
        id = 2
    )
    val option4 = Option(
        title = "DND OFF",
        function = { scope.launch { filterFun.interruptionFilterAll() } },
        icon = Icons.Filled.DoNotDisturbOff,
        selected = selected,
        enabled = enabled,
        id = 3
    )
And eventually I call the functions as shown above. I now realise that I am launching each function twice. Maybe that's the problem...
Copy code
ElevatedButton(
        onClick = {
            scope.launch {
                filterFun.interruptionFilterAll()
                delay(1000L)
                option.function()
            }
        },
c
setInterruptionFilter itself is not a suspend function, so you don’t need to wrap it in
suspend
. I think this is causing you some confusion. The main problem is that you’re calling
launch
within a
launch
, but the coroutine scopes of the two
launch
blocks are not connected to each other, so it’s breaking the concept of “structured concurrency”. You have
ElevatedButton
launch a coroutine, which calls
option.function()
which is not marked with
suspend
. So when the implementation of
option.function()
calls
launch
within itself, it’s just running in a completely separate coroutine, with no relation to the block within
ElevatedButton
. What you would typically do instead is make your
function
lambda
suspend ()->Unit
instead so that it can call other suspend functions, but within the CoroutineScope of
ElevatedButton
. But as I mentioned at the beginning, in this specific case, you shouldn’t need to mark anything
suspend
at all, because it’s really not doing anything for you and is just making things more confusing
n
Ok, many thanks for the detailed explanation! This is very helpful! 😊
And it works!