在 Kotlin 中执行第二个函数之前,如何等待第一个函数完成?

时间:2021-06-03 16:36:02

标签: android kotlin kotlin-coroutines coroutine

所以我有一个简单的代码

try_button.setOnClickListener {
        GlobalScope.launch {
            fun1()
            fun2()
        }
    }

private fun fun1(){
    Timer().schedule(5000){
        println("THIS IS THE FIRST FUNCTION")
    }
}
private fun fun2(){
    println("THIS IS THE SECOND FUNCTION")
}

我想运行第一个函数,第一个函数完成后,继续第二个函数。

我尝试了很多代码,但我总是得到结果

THIS IS THE SECOND FUNCTION
THIS IS THE FIRST FUNCTION

我可以等待第一个函数完成后再继续第二个函数吗?

4 个答案:

答案 0 :(得分:0)

添加暂停关键字。它会暂停你的执行

try_button.setOnClickListener {
            GlobalScope.launch {
                fun1()
                fun2()
            }
        }

suspend fun fun1(){
    delay(1000)
    println("THIS IS THE FIRST FUNCTION")
}
fun fun2(){
    println("THIS IS THE SECOND FUNCTION")
}

答案 1 :(得分:0)

您正在使用 launch 但未使用 suspend 函数。使您的函数挂起函数并使用 delay,这是一个suspend函数,旨在等待。

try_button.setOnClickListener {
        GlobalScope.launch {
            fun1()
            fun2()
        }
    }

private suspend fun fun1(){
    delay(5000)
    println("THIS IS THE FIRST FUNCTION")
}
private suspend fun fun2(){
    println("THIS IS THE SECOND FUNCTION")
}

有关协程如何工作的更多信息,请查看 the documentation

答案 2 :(得分:0)

根据您的用例,更好的选择将使用 asyncawait 它的基本功能,您将请求 fun1 它在完成后等待结果 1 它将进行进一步的处理即使您在 fun1 中设置了一些延迟,它仍然会依次运行 fun1 然后 fun2,这是 fun2,这是代码片段:

只是从某处获取数据的常规函数​​

private suspend fun fun1(): String {
    delay(3000L)
    return "Result 1"
}


private fun fun2(): String {
    return "Result 2"
}

顺序调用:

   val result1 = async {
            fun1()
        }
        println(result1.await())


        val result2 = async {
            fun2()
        }
        println(result2.await())

输出

Result 1
Result 2

答案 3 :(得分:0)

如果替换,使用 suspend for fun1 是正确的

Timer().schedule(5000) {
    println("THIS IS THE FIRST FUNCTION")
}

delay(5000L)
println("THIS IS THE FIRST FUNCTION")

所以:

private suspend fun fun1() {
    delay(5000L)
    println("THIS IS THE FIRST FUNCTION")
}

private fun fun2() {
    println("THIS IS THE SECOND FUNCTION")
}

Timer().schedule(5000) 不是挂起函数,所以挂起 fun1 不会做任何事情。事实上 Timer().schedule(5000) 使用与 GlobalScope.launch 不同的线程,因此该操作是在协程线程池之外执行的,这意味着除了手动(例如使用一个信号量)。

如果您想对结果进行同步,则使用 async / await 将是一个解决方案(您的问题另有含义)。如果您想使用 async,则只有 fun1 需要 async/await,因为 fun2 只是一个常规函数(无需延迟,无需暂停)。

只是为了好玩,使用信号量的解决方案

val lock = Semaphore(1)

fun main() {
    GlobalScope.launch {
        fun1()
        fun2()
    }
}

private suspend fun fun1() {
    lock.acquire()
    Timer().schedule(5000) {
        println("THIS IS THE FIRST FUNCTION")
        lock.release()
    }
}

private suspend fun fun2() {
    lock.acquire()
    println("THIS IS THE SECOND FUNCTION")
}

信号量可以在挂起之前获得一次(fun2),一旦许可被释放(fun1)就可以恢复。

相关问题