在我的 Viewmodel 類中,我執行以下代碼:
init {
viewModelScope.launch(Dispatchers.IO) {
val homepageItemsCall = async { getHomepageItems() }
val carouselItemsCall = async { getCarouselItems() }
homepageItemsCall.await()
carouselItemsCall.await()
checkFavoriteStatus(homeItemsTest)
carouselItems.postValue(carouselItemsTest)
}
}
這是我的 homepageItemsCall 的樣子:
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))
}
)
}
我的期望是這樣的:
- 我在 ViewmodelScope 上創建了一個協程,它將在 init 塊中執行代碼。
- 因為我使用的是異步等待,所以在我的 API 呼叫完成之前我的代碼不會被執行。這意味著我的兩個 API 呼叫都會成功/失敗,之后,我的代碼可以轉到下一行:“checkFavoriteStatus(homeItemsTest)”。
但它不是那樣作業的。即使我使用了異步等待,程式也會在我的 API 呼叫完成之前轉到 checkFavoriteStatus(homeItemsTest) 行。我認為 async await 掛起/阻止正在執行異步代碼的協程(在這種情況下,正在執行我的整個 init 塊的協程..?我做錯了什么嗎?
如果是,等待我的 API 呼叫完成然后使用協程轉到下一個代碼的最佳方法是什么?
uj5u.com熱心網友回復:
您對 async-await 部分的看法基本正確。問題出在getHomepageItems()函式上。你launch()一切都是異步的,因此這個函式會立即回傳。此外,getResult()似乎也是異步的。
制作此功能suspend并使所有代碼同步。生成的代碼可能如下所示,但可能需要額外調整:
private suspend fun getHomepageItems() {
suspendCoroutine<Unit> { cont ->
restService.getHomepage().getResult(
success = { value ->
homeItemsTest = value
cont.resume(Unit)
},
genericError = { _, message ->
error.postValue(message)
cont.resume(Unit)
},
networkError = {
error.postValue(TranslationManager.getString(TKeys.LOGIN_NETWORK_ERROR))
cont.resume(Unit)
}
)
}
}
根據您使用的其余客戶端庫,執行起來會容易得多,因為許多此類別庫已經支持協程和掛起函式。在這種情況下,他們通常會提供掛起 API,因此您不必自己將回呼轉換為掛起。請參閱庫的檔案。
uj5u.com熱心網友回復:
它是Kotlin 協程的重復 等待 2 個或更多不同的并發請求
你應該使用awaitAll
uj5u.com熱心網友回復:
如果你想在 API 呼叫完成后做一些事情,你可以做這樣的事情
init {
viewModelScope.launch(Dispatchers.IO) {
homepageItemsCall = getHomepageItems()
carouselItemsCall = getCarouselItems()
}.invokeOnCompletion{
checkFavoriteStatus(homeItemsTest)
carouselItems.postValue(carouselItemsTest)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/381553.html
下一篇:使用當天的開始時間獲取日期
