我将在视图模型中启动一个协程来执行一些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中的更改反映到用户界面中,这就是我使用流的原因.在调用loadProductsFromDatabaseAsFlow,然后在Collect块中切换到Main时,是否需要将上下文切换到Dispatcher.IO?再问一次,正确的方式是什么?

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

推荐答案

这两种方法有什么不同?哪种方法是正确的?

async主要用于并行执行任务,返回一些结果.在您的例子中,您只启动了一个任务,所以我认为withContext(Dispatchers.IO)在这里是首选的.

我是否需要在呼叫loadProductsFromDatabaseAsFlow时将上下文切换到Dispatchers.IO,然后在Collect块中切换到Main

不,你不需要.您可以在不切换上下文的情况下收集数据.Flow.collect()方法为suspend,则suspend方法的主要目的之一是在不阻塞Main线程的情况下在Main上下文中调用.他们只是暂停协程,而不是当前的线程.

Kotlin相关问答推荐

这些Kotlin函数等效吗?

Kotlin—列出具有不同T的列表之间的操作'

Kotlin是否针对范围和进度优化sum()?

在构造函数中创建内部类实例时,只能使用包含类的接收器调用内部类的构造函数

仅某些用户出现 DateTimeFormatter 错误

在 Kotlin 中,为什么我们要在闭包中捕获值

列表在 android WebView 中没有正确迭代

Kotlin 中的 maxOf() 和 max() 方法有什么区别?

如何访问嵌套在另一个 map 中的 map 中的值(在 kotlin 中)

Kotlin:不允许在辅助构造函数参数上使用val

Kotlin 方法重载

kotlin 扩展属性的惰性初始化器中的这个引用

Kotlin 中的数据类

使用 Kotlin 创建新目录,Mkdir() 不起作用

如果我可以将 Flow 和 StateFlow 与生命周期范围 \ viewLifecycleOwner.lifecycleScope 一起使用,那么在 ViewModel 中使用 LiveData 有什么意义

Android Studio 将 Java 转换为 Kotlin 错误无法推断此参数的类型

空对象引用上的 TransitionSet ArrayList.size()

使用 kotlin 每 3 位数添加逗号或点

lateinit 的 isInitialized 属性在伴随对象中不起作用

RecyclerView 适配器中的导航组件