如何进行多个异步网络调用并一次更新插入它们?

问题描述 投票:0回答:1

我有一个采用 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())
        }
    }
}
android mvvm kotlin-coroutines
1个回答
0
投票

您可以使用 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)
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.