Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在Kotlin中执行第二个函数之前,如何等待第一个函数完成?_Android_Kotlin_Kotlin Coroutines_Coroutine - Fatal编程技术网

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

Android 在Kotlin中执行第二个函数之前,如何等待第一个函数完成?,android,kotlin,kotlin-coroutines,coroutine,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 fu

所以我有一个简单的代码

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

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

添加suspend关键字。它将暂停执行你的死刑

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")
}

您正在使用
launch
,但未使用
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")
}

请查看有关协同路由如何工作的更多信息。

根据您的用例,更好的选择将是使用
async
wait
它的基本功能,您将请求fun1,它将等待结果1一旦完成,它将进入下一个过程,即fun2,即使您在fun1中设置了一些延迟,它仍将按顺序运行fun1,然后再运行fun2,以下是代码段:

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

顺序呼叫:

输出:


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

Timer().schedule(5000) {
    println("THIS IS THE FIRST 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)后恢复。

使用runBlocking.@RishabhKumarSingh我想向任何可能看到此评论的人指出,这是<代码>运行阻塞不应在生产代码中使用,除非在非常特殊的情况下使用。(另外,它实际上根本解决不了这个问题,因为两个函数都会立即返回而不挂起,而这里的问题更多的是一个逻辑错误…@Moira非常感谢。如果我想要一个数据库操作,并且没有结果就无法继续,这是一个疑问。那我怎么办?我应该不使用挂起函数吗?fun2不需要使用async/await,因为fun2只是一个常规函数,而不是挂起函数function@EmanuelMoecklin用例是,他想要一些连续运行的东西,即使有延迟,而且不仅仅是关于挂起函数。什么是
async
它使请求成功或失败,什么是
等待
它等待进一步处理的结果。fun2也是如此。async/await不仅用于挂起函数,而且有助于使代码顺序化,或者您也可以使其并行化。此外,我还要提到这个kotlinconf:默认情况下,挂起函数是顺序的,因此不需要异步/等待。如果要同时运行多个产生结果的协同路由,则使用Async/await。Async生成一个类似于Java特性或JavaScript承诺的延迟对象。重要的是异步是热的,所以它会立即开始执行。另请参见。为了使“热”部分更清楚,使用您的代码,fun1和fun2将立即被调用,因此如果您将print语句放在两个函数的顶部,即使结果按顺序返回,它也将同时打印这两个函数。这与OP想要的正好相反,并发执行与顺序执行。没有必要暂停Fun2感谢您的帮助,它可以工作,但如果我的fun1试图从Firebase获得结果,它就不起作用
Result 1
Result 2
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")
}
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")
}