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