安卓kotlin协同程序异步等待



在Viewmodel类中,我执行下一个代码:

init {
viewModelScope.launch(Dispatchers.IO) {
val homepageItemsCall = async { getHomepageItems() }
val carouselItemsCall = async { getCarouselItems() }

homepageItemsCall.await()
carouselItemsCall.await()
checkFavoriteStatus(homeItemsTest)
carouselItems.postValue(carouselItemsTest)
}
}

这就是我的主页ItemsCall的样子:

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))
}
)
}

我的期望是这样的:

  1. 我在ViewmodelScope上创建了一个协程,它将在init块中执行代码
  2. 由于我使用的是async wait,所以在我的API调用完成之前,我的代码不会被执行。这意味着我的两个API调用都将进入成功/失败,然后,我的代码可以进入下一行:;checkFavoriteStatus(homeItemsTest(">

但它不是那样工作的。程序在我的API调用完成之前进入checkFavoriteStatus(homeItemsTest(行,即使我使用了异步等待。我认为async wait挂起/阻止正在执行异步代码的协同程序(在这种情况下,是正在执行我的整个init块的协同程序…?我有什么错吗?

如果是的话,等待API调用完成,然后使用协程进入下一个代码的最佳方式是什么?

编辑这些是getHomePage和getResult函数:

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()
}

如果您想在API调用完成后做一些事情,您可以做一些类似的事情

init {
viewModelScope.launch(Dispatchers.IO) {
homepageItemsCall =  getHomepageItems()
carouselItemsCall =  getCarouselItems() 

}.invokeOnCompletion{
checkFavoriteStatus(homeItemsTest)
carouselItems.postValue(carouselItemsTest)
}
}

尝试将函数getHomepageItemsgetCarouselItems设置为suspend,如下所示:

private suspend fun getHomepageItems() {
restService.getHomepage().getResult(
success = { value ->
homeItemsTest = value
},
genericError = { _, message ->
error.postValue(message)
},
networkError = {
error.postValue(TranslationManager.getString(TKeys.LOGIN_NETWORK_ERROR))
}
)
}

因为async创建了一个协程来运行代码,await会等待它并从中获得结果。但在您的代码中,async中的协程是创建另一个await不会等待它的协程

最新更新