In my Viewmodel class I do the next code:
init {
viewModelScope.launch(Dispatchers.IO) {
val homepageItemsCall = async { getHomepageItems() }
val carouselItemsCall = async { getCarouselItems() }
homepageItemsCall.await()
carouselItemsCall.await()
checkFavoriteStatus(homeItemsTest)
carouselItems.postValue(carouselItemsTest)
}
}
This is how my homepageItemsCall looks:
private fun getHomepageItems() = viewModelScope.launch(Dispatchers.IO) {
restService.getHomepage().getResult(
success = { value ->
homeItemsTest = value
},
genericError = { _, message ->
error.postValue(message)
},
networkError = {
error.postValue(TranslationManager.getString(TKeys.LOGIN_NETWORK_ERROR))
}
)
}
My expectation was like this:
- I create a coroutine on ViewmodelScope that is going to execute code in init block.
- since I am using async await, my code will not be executed until my API calls are done. This means both of my API calls will go to success/failure and after that, my code can go to the next line: "checkFavoriteStatus(homeItemsTest)".
But it doesn't work like that. Program goes to checkFavoriteStatus(homeItemsTest) line before my API calls are done even though I used async await. I thought that async await suspends/blocks coroutine that is executing async code (in this case, coroutine that is executing my whole init block..? Did I get something wrong?
And if yes, what is the best way to wait for my API calls to finish and then go to the next code by using coroutines?
Edit these are getHomePage and getResult functions:
suspend fun <T> ResultWrapper<T>.getResult(
success: suspend (value: T) -> Unit,
genericError: (suspend (code: Int?, message: String?) -> Unit)? =
null,
networkError: (suspend () -> Unit)? = null,
error: (suspend () -> Unit)? = null
) {
when (this) {
is ResultWrapper.Success -> {
success(value)
}
is ResultWrapper.GenericError -> {
genericError?.let { it(code, errorMessage) }
}
is ResultWrapper.NetworkError -> {
networkError?.let { it() }
}
}
if (this is ResultWrapper.NetworkError || this is ResultWrapper.GenericError)
error?.let { it() }
}
suspend fun getHomepage() = safeApiCall(Dispatchers.IO) {
apiClient.getHomepageElements()
}
restService.getHomepage()or.getResult()suspend? If they are not getHomepageItems function will return immediately, which you probably don't want here.getHomepage()andgetResult()provided by the library or implemented by you? Could you share their source code?GetHomePage()instead ofrestService.getHomepage(). Secondly, there is a weird habit in this code to mark all functions assuspend, even if they don't really suspend and start every function withlaunch().launch()makes it impossible / much harder to track the operation, wait for it to finish and get its results.