android - Kotlin Coroutine Retrofit - 链式网络调用

标签 android kotlin kotlin-coroutines

我正在尝试使用 Kotlin Coroutines + Retrofit 进行网络调用,但我目前的实现有两个问题。

A)只有在我的循环完成后才会返回。

B)似乎要等待循环中的每个调用完成,然后再进行下一个调用。

我正在与之交互的 API 要求我进行初始提取,返回 itemId 的数组

[ 1234, 3456, 3456 ... ]

对于上述响应中的每个项目,使用 id 获取该项目
{ id: 1234, "name": "banana" ... }

我目前的实现如下,我做错了什么?
suspend operator fun invoke(feedType: String): NetworkResult<List<MyItem>> = withContext(Dispatchers.IO) {
    val itemList: MutableList< MyItem > = mutableListOf()
    val result = repository.fetchItems()
    when (result) {
        is NetworkResult.Success -> {
            itemList.addAll(result.data)
            for (i in itemList) {
                val emptyItem = result.data[i]
                val response = repository.fetchItem(emptyItem.id)

                when (response) {
                    is NetworkResult.Success -> {
                        val item = response.data
                        emptyItem.setProperties(item)
                    }
                }
            }
        }
        is NetworkResult.Error -> return@withContext result
    }
    return@withContext NetworkResult.Success(itemList)
}

最佳答案

我建议您使用 async分别处理每个项目:

suspend operator fun invoke(feedType: String): NetworkResult<List<MyItem>> = withContext(Dispatchers.IO) {
    when (val result = repository.fetchItems()) { // 1
        is NetworkResult.Success -> {
            result.data
                .map { async { fetchItemData(it) } } // 2
                .awaitAll() // 3
            NetworkResult.Success(result.data)
        }
        is NetworkResult.Error -> result
    }
}

private suspend fun fetchItemData(item: MyItem) {
    val response = repository.fetchItem(item.id)
    if (response is NetworkResult.Success) {
        item.setProperties(response.data)
    }
}

在这段代码中,我们首先调用 fetchItems获取项目 ID (1)。然后我们调用fetchItem同时为每个项目 (2)。使用协程和 async 可以轻松完成.然后我们等到所有数据都被获取(3)。

关于android - Kotlin Coroutine Retrofit - 链式网络调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57940091/

相关文章:

java - 在 android 中使用 ESRI shapefile

android - 如何按名称(字符串)而不是整数获取资源

java - okhttp中的多个连接websocket

android - 如何从 Sqlite 数据库获取选定的 Spinner 值 ID

android - 将 Java Lambda 转换为 Kotlin Lamba 时出错

android - 集成使用 Kotlin Coroutines 依赖问题构建的库模块

kotlin - 如何在 Kotlin Actor 中获得非阻塞无限循环?

http - 如何在 Kotlin 中将 win1251 编码转换为 UTF8?

spring - 如何返回我的自定义 json 文件而不是生成 Spring Boot 的默认 json 文件?

android - 当应用程序启动依赖于网络调用时,如何处理 Android 中的进程重新创建?