I'm trying to use Kotlin Coroutines + Retrofit to make my network calls, but my current implementation has two problems.
A) It only returns once my loop has completed.
B) it seems to wait for each call in my loop to complete before making the next one.
The API I'm interacting with requires me to make an initial fetch, returning an array of itemId's
[ 1234, 3456, 3456 ... ]
and for each item in the above response, fetch that item with id
{ id: 1234, "name": "banana" ... }
My current implementation is as follows, what am I doing wrong?
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)
}
I would like to propose you to use async
to process every item separately:
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)
}
}
In this code, at first, we make a call to fetchItems
to get the items ids (1). Then we make a call to fetchItem
for every item at the same time (2). It can be easily done with coroutines and async
. Then we wait until all data will be fetched (3).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With