kotlin - Kotlin 协程中 IO 和 UI 之间切换的正确方法是什么?

标签 kotlin kotlin-coroutines coroutine kotlin-flow

我正在 View 模型中启动一个协程来执行一些 IO 操作,例如 api 调用和数据库查询。我知道有几种方法可以做到这一点,这就是为什么我很困惑哪种方法是正确的。

两者之间有什么区别,哪一个是正确的方法?

fun loadProducts() {
    viewModelScope.launch {    
        val productsDeferred = async(Dispatchers.IO) { downloadProducts() }
        this.products = productsDeferred.await()        
    }
}


fun loadProducts2() {
    viewModelScope.launch {    
        this.products = withContext(Dispatchers.IO) { downloadProducts() }
    }
}

在此示例中,我使用流程从 roomdb 加载产品。我希望 db 中的更改能够反射(reflect)到 UI,这就是我使用流程的原因。调用 loadProductsFromDatabaseAsFlow 时是否需要将上下文切换到 Dispatchers.IO,然后切换到收集 block 中的 Main?再说一遍,正确的方法是什么?

fun loadProducts3() {
    viewModelScope.launch {
        loadProductsFromDatabaseAsFlow().collect {
            this.products = it
        }
    }
}

最佳答案

What's the difference between the two and which is the proper approach?

async主要用于并行执行任务,返回一些结果。在你的情况下,你只启动一项任务,所以我会说 withContext(Dispatchers.IO)这里是首选。

Do I need to switch context to Dispatchers.IO when calling loadProductsFromDatabaseAsFlow and then switch to Main in the collect block?

不,你不需要。您无需切换上下文即可收集数据。 Flow.collect()方法是suspendsuspend的主要用途之一方法将在 Main 中调用上下文而不阻塞 Main线。他们只是挂起协程,而不挂起当前线程。

关于kotlin - Kotlin 协程中 IO 和 UI 之间切换的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73376038/

相关文章:

java - 如何在android中创建水平滚动分组条形图

android - Coroutine 的 Deferred 类型为 null 会怎样?

kotlin - Kotlin 如何通过运行示例解释 {} 或 ()

android - 类型不匹配。必需的 map <String, Any> 找到的 map <String, Any?>

kotlin - 在Kotlin Anko中使用ConstraintLayout

kotlin - 如何将 Kotlin 从 1.2 迁移到 Kotlin 1.3.0,然后在演示者函数中使用 async、UI 和 bg

kotlin - 为什么执行挂起的存储库函数而不执行非挂起的存储库函数?

android - 如何在 OnCompleteListener Firebase 中使用 Async/Await/Coroutines

Kotlin 协程进度计数器

python - 生成器函数和异步生成器函数的用途有什么区别