我有一个采用 MVVM 架构的应用程序。 DB 是唯一的事实来源。如果数据过时,我想通过从网络获取最新信息来刷新记录。 我必须为数据库中的每条记录进行单独的网络调用。我需要一次将它们全部更新,以便它们都具有相同的
updated_at
,这对于下一次过时的计算来说非常有用。
这是存储库中刷新当前记录的方法:
// locationApi.getLocation(...) is a suspend function in a Retrofit interface
private fun refresh(locations: List<LocationEntity>) {
coroutineScope.launch(ioDispatcher) {
locations.map {
it.update(locationApi.getLocation(it.latitude, it.longitude))
}.let {
locationDao.upsertAll(it)
}
}
}
问题是 API 调用是在
map
内按顺序完成的,需要一段时间才能完成。如何使 API 调用异步并立即更新插入结果?我找到了以下解决方案,但我想知道可能的解决方案及其比较。
解决方案:async+awaitAll
private fun refresh(locations: List<LocationEntity>) {
coroutineScope.launch(ioDispatcher) {
locations.map {
async { it.update(locationApi.getLocation(it.latitude, it.longitude)) }
}.let {
locationDao.upsertAll(it.awaitAll())
}
}
}
您可以使用 Kotlin 在 Android 中进行多个异步网络调用,并使用 Kotlin 的协程和 async 函数集中处理它们。要立即更新插入结果,可以使用awaitAll 收集结果并执行更新插入操作。这是例子
class MainRepository(private val apiService: YourApiService, private val dao: YourDaoName) {
suspend fun fetchDataAndUpsert () {
// Start multiple asynchronous network calls using coroutines
val networkCall1 = async { apiService.getDataFromNetwork1() }
val networkCall2 = async { apiService.getDataFromNetwork2() }
// Await for both network calls to complete
val response1 = networkCall1.await()
val response2 = networkCall2.await()
// Extract data from responses (assuming data is in response body)
val dataFromNetwork1 = response1.body()
val dataFromNetwork2 = response2.body()
// Convert network data to entities for Room
val dataEntities = mutableListOf<DataEntity>()
dataFromNetwork1?.let { dataEntities.addAll(convertToEntity(it)) }
dataFromNetwork2?.let { dataEntities.addAll(convertToEntity(it)) }
// Upsert data into the Room database
if (dataEntities.isNotEmpty()) {
dao.upsertData(dataEntities)
}
}