繁体   English   中英

等待另一种方法,直到协程完成 [Android Kotlin]

[英]Make wait another method until coroutine finishes [Android Kotlin]

我想让等待方法getCurrentUser或通知该方法,直到协程完成。 因为在协程中初始化的变量conversationKit在方法中使用。 协程在方法integrateConversationKit中启动。这两种方法都在MainActivityonCreate中调用。 但是我收到错误lateinit property conversationKit has not been initialized。

    class ConversationKitService(private val context: Context) {
       private val scope = CoroutineScope(Dispatchers.Main)
       lateinit var conversationKit: ConversationKit
    
        fun integrateConversationKit() {
        
        
                val job = scope.launch {
                    val result = conversationKitFactory.create(
                        settings = settings
                    )
        
                    when (result) {
        
                        is ConversationKitResult.Success -> conversationKit = result.value
                        is ConversationKitResult.Failure -> println(result.message)
                    }
                }
        
        
            }
        
        
            fun getCurrentUser(): User? {
        
                return conversationKit.getCurrentUser()
            }
    }

您可以使用Flow来响应式更新conversationKit ,然后返回它的第一个非空值

 class ConversationKitService(private val context: Context) {
       private val scope = CoroutineScope(Dispatchers.Main)
       private val conversationKit = MutableStateFlow<ConversationKit?>(null)
    
       fun integrateConversationKit() {
                val job = scope.launch {
                val result = conversationKitFactory.create(
                        settings = settings
                    )
        
                    when (result) {
        
                        is ConversationKitResult.Success -> conversationKit.value = result.value
                        is ConversationKitResult.Failure -> println(result.message)
                    }
                }
        
        
            }
        
        
            suspend fun getCurrentUser() = conversationKit.first{ it != null }.getCurrentUser()
            
    }

我只会让getCurrentUser成为一个挂起调用,从缓存结果的内部挂起调用中获取ConversationKit

   class ConversationKitService(private val context: Context) {
       @Volatile
       private var conversationKit: ConversationKit? = null

       ...

       suspend fun getCurrentUser() = getConversationKit()?.getCurrentUser() 

       private suspend getConversationKit(): ConversationKit? {
           if (conversationKit != null) return conversationKit
           val result = conversationKitFactory.create(settings = settings)
           conversationKit = when (result) {
               is ConversationKitResult.Success -> result.value
               is ConversationKitResult.Failure -> null           
           } 
           return conversationKit
       }          
   }

然后, null值意味着检索该值时出错。 您还可以将其包装在某种Result中,以便返回成功/失败而不是可为空的值。

但是,如果您真正想要做的是使getCurrentUser成为一个不需要协程来使用它的非挂起阻塞调用,那么您可以使用runBlocking

   class ConversationKitService(private val context: Context) {
       @Volatile
       private var conversationKit: ConversationKit? = null

       ...

       fun getCurrentUser() = runBlocking { 
           getConversationKit()?.getCurrentUser()
       }

       private suspend getConversationKit(): ConversationKit? {
           if (conversationKit != null) return conversationKit
           val result = conversationKitFactory.create(settings = settings)
           conversationKit = when (result) {
               is ConversationKitResult.Success -> result.value
               is ConversationKitResult.Failure -> null           
           } 
           return conversationKit
       }          
   }

不过,我不会真的推荐这种方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM