android - 多次从 ViewModel 调用一种方法的好解决方案
问题描述
我需要从 MVVM 多次调用一种方法以进行 API 调用并将结果发送到回收站视图。我不知道用户需要这样做多少次,因为它取决于列表大小。例如:
list: ["FirstElement", "SecondElement", "..", "..."]
在代码中,我尝试了循环中的调用方法:
for (city in list) {
viewModel.getCurrentWeatherByCity(city, appID, unit).observe(viewLifecycleOwner, {
result.add(it) // here is arraylist for recyclerview
})
}
val adapterRecycler = LocationListWeatherRecyclerAdapter(result) // init adapter for recycler
setUpRecyclerData(adapterRecycler) // method for setup recyclerview
查看模型方法:
fun getCurrentWeatherByCity(city: String, appID: String, units: String): LiveData<WeatherModel> {
return repository.getCurrentWeatherByCity(city, appID, units)
}
和存储库方法:
fun getCurrentWeatherByCity(city: String, appID: String, units: String ) : LiveData<WeatherModel> {
apiService.getCurrentWeatherByCity(city, appID, units).enqueue(object : Callback<WeatherModel>{
override fun onResponse(call: Call<WeatherModel>, response: Response<WeatherModel>) {
if (response.isSuccessful) {
weatherData.postValue(response.body())
} else {
}
}
override fun onFailure(call: Call<WeatherModel>, t: Throwable) {
}
})
return weatherData
}
但我知道这是错误的解决方案,因为结果是在后台做的并且是错误的。这 for 可以从循环中的 4 次迭代中返回数组中的 80 个项目。
你知道我能做些什么吗?感谢帮助
解决方案
使用挂起函数可以更轻松地解决这个问题,我就是这样做的。
首先让你的仓库使用一个直接返回的挂起函数WeatherModel
而不是一个LiveData<WeatherModel>
. 它可以在失败时返回 null,或者如果你愿意,你可以做一些更复杂的事情。
suspend fun getCurrentWeatherByCity(city: String, appID: String, units: String ) : WeatherModel? {
return runCatching { apiService.getCurrentWeatherByCity(city, appID, units).await() }
.getOrNull()
}
然后,您可以在 ViewModel 中创建一个函数,该函数接受城市列表并并行运行 api 调用,如下所示:
fun getCurrentWeatherByCities(cities: List<String>, appID: String, units: String) = liveData<List<WeatherModel>> {
val weatherModels = cities.map { city ->
async { repository.getCurrentWeatherByCity(city, appID, units) }
}
.awaitAll()
.filterNotNull()
emit(weatherModels)
}
然后在你的片段中,观察它并在观察者中设置适配器列表。
viewModel.getCurrentWeatherByCities(cities, appID, unit).observe(viewLifecycleOwner, {
val adapterRecycler = LocationListWeatherRecyclerAdapter(it)
setUpRecyclerData(adapterRecycler)
}
推荐阅读
- xslt-1.0 - 如何放置“和”条件以从 xslt 中删除 xml 元素
- javascript - 基于对象的日期、时间排序数组
- python - 如何使用 python(服务器)和 Angular(客户端)从 SQL Server 发送 pdf 数据和保存
- css - 以字体显示标题 - 真棒图标
- php - simplexml_load_file 通过 url 读取远程 xml,由对等方重置连接
- sql-server - 在临时表中插入相同表和不同变量的值
- javascript - 在数组中查找模式
- java - Vaadin Flow:组件和元素之间的区别
- sql - 修剪字符串直到一个值
- python - numpy数组的元素之和与总数不同