我对协程比较陌生,所以我想知道如何在不大量重构Android代码的情况下解决本地的小问题。
这里是一个简单的设置。我的ViewModel从存储库中调用suspend函数:// ...ViewModel.kt
fun loadData() {
viewModelScope.launch {
val data = dataRepository.loadData()
}
}
这非常方便,因为我有一个由Android准备的viewModelScope,并且从我的存储库中调用了一个suspend函数。我不在乎存储库如何加载数据,我只是暂停直到数据返回给我。
我的数据存储库使用Retrofit进行了多次调用://...DataRepository.kt
@MainThread
suspend fun loadData(): ... {
// Retrofit switches the contexts for me, just
// calling `suspend fun getItems()` here.
val items = retrofitApi.getItems()
val itemIDs = items.map { it.id }
// Next, getting overall list of subItems for each item. Again, each call and context
// switch for `suspend fun retrofitApi.getSubItems(itemID)` is handled by Retrofit.
val subItems = itemIDs.fold(mutableListOf()) { result, itemID ->
result.apply {
addAll(retrofitApi.getSubItems(itemID)) //
}
}
return Pair(items, subItems)
}
如您所见,由于loadData()是挂起函数,对retrofitApi.getSubItem(itemID)的所有调用将顺序执行。
但是,我想并行执行它们,就像协程中的async() / await()一样。
我想保持ViewModel代码不变-它不在乎数据的加载方式,只需从自己的作用域启动暂停功能即可。我也不想将任何范围或其他对象传递到我的存储库。
如何在暂停功能中执行此操作?范围在某种程度上隐含地存在吗?呼叫async()是否可能/允许/良好做法?