我正在尝试使用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)
}
答案 0 :(得分:1)
我建议您使用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)。