使用 Kotlin 协程并行多个网络调用
应用程序的主屏幕是我们需要填充多个视图的地方,例如促销横幅、显示应用程序核心内容的列表、基本用户信息等,当您获得所有需要的数据时,用数据填充所有这些视图真的很容易一个 API 调用,但并非每次都如此。很多时候,我们需要调用多个 API 请求来获取客户端设备上所需的数据,并等待它们一个接一个地执行,获取结果并进行处理。我们将学习如何使用 Kotlin 协程进行并行多个网络调用。我们已经学会了使用 Kotlin Coroutines 和 LiveData 在 ViewModel 中编写代码,这些代码遵循基本的 MVVM 架构。本教程还将帮助您使用 Kotlin 协程并行执行任何类型的后台任务。
是的,进度视图仍在主屏幕中旋转,那么我们如何通过并行执行 API 请求比以前更早地取下微调器,让我们先看一下代码。
Kotlin
class HomeViewModel(val homeDataUsecase: HomeDataUsecase
):BaseViewModel() {
fun getAllData() {
viewModelScope.launch {
coroutineScope {
val bannerResponse:BaseResponse?
val contentResponse: BaseResponse?
val userResponse: BaseResponse?
val call1 = async { homeDataUsecase.getBannerdata()}
val call2 = async { homeDataUsecase.getContentData()}
val call3 = async { homeDataUsecase.getUserdata() }
try {
bannerResponse = call1.await()
contentResponse = call2.await()
userResponse = call3.await()
} catch (ex: Exception) {
ex.printStackTrace()
}
processData(bannerResponse, contentResponse, userResponse)
}
}
}
Kotlin
viewModelScope.launch {
withContext(dispatcherProvider.heavyTasks) {
val apiResponse1 = api.get1() // suspend function
val apiResponse2 = api.get2() // suspend function
if (apiResponse1.isSuccessful() && apiResponse2.isSuccessful() { .. }
}
}
Kotlin
viewModelScope.launch {
withContext(dispatcherProvider.heavyTasks) {
val multipleIds = listOf(1, 2, 3, 4, 5, ..)
val content = arrayListOf()
multipleIds.forEach { id ->
// suspend function
val apiResponse1 = api.get1(id)
if (apiResponse1.isSuccessful()) {
content.find { it.id == id }.enable = true
}
}
liveData.postValue(content)
}
}
当您必须进行不同的 API 调用并等待时,您可以执行以下操作:
科特林
viewModelScope.launch {
withContext(dispatcherProvider.heavyTasks) {
val apiResponse1 = api.get1() // suspend function
val apiResponse2 = api.get2() // suspend function
if (apiResponse1.isSuccessful() && apiResponse2.isSuccessful() { .. }
}
}
但是如果我必须使用不同的参数执行多个并发的相同 API 调用会发生什么:
科特林
viewModelScope.launch {
withContext(dispatcherProvider.heavyTasks) {
val multipleIds = listOf(1, 2, 3, 4, 5, ..)
val content = arrayListOf()
multipleIds.forEach { id ->
// suspend function
val apiResponse1 = api.get1(id)
if (apiResponse1.isSuccessful()) {
content.find { it.id == id }.enable = true
}
}
liveData.postValue(content)
}
}
第二种方法的问题是它会遍历多个列表的所有 id 并进行异步调用,但内容可能会在此之前发布。如何等待每个循环的所有响应完成,然后才能查看内容的 postValue?是的,这就是使用 Kotlin Coroutines 进行并行多个网络调用的基本思想