如何用协程异步处理数据?实现并行请求结果实时返回
实现并行请求并实时处理返回结果
你当前的代码会等待所有异步任务完成后才统一处理结果,要实现每个请求响应返回后立即更新UI,核心思路是让每个并行任务在自身完成后直接触发结果传递,不需要等待其他任务。
核心实现方案
用launch替代async启动每个并行任务,每个任务执行完毕后立刻将结果传递给ViewModel,再由ViewModel通知Fragment实时展示。
1. 并行请求并实时通知ViewModel
suspend fun fetchAsyncData(viewModel: YourViewModel) = coroutineScope { // 四个任务并行启动,每个任务完成后立即推送结果 launch { val result = repository.taskFirst() viewModel.updateFirstData(result) } launch { val result = repository.taskSecond() viewModel.updateSecondData(result) } launch { val result = repository.taskThird() viewModel.updateThirdData(result) } launch { val result = repository.taskFourth() viewModel.updateFourthData(result) } }
2. ViewModel用StateFlow管理状态
ViewModel通过StateFlow持有各请求的结果,Fragment可观察这些Flow获取实时更新:
class YourViewModel : ViewModel() { // 定义各请求结果的StateFlow,初始值为null表示未加载 private val _firstData = MutableStateFlow<FirstResult?>(null) val firstData = _firstData.asStateFlow() private val _secondData = MutableStateFlow<SecondResult?>(null) val secondData = _secondData.asStateFlow() private val _thirdData = MutableStateFlow<ThirdResult?>(null) val thirdData = _thirdData.asStateFlow() private val _fourthData = MutableStateFlow<FourthResult?>(null) val fourthData = _fourthData.asStateFlow() // 更新对应请求的结果 fun updateFirstData(result: FirstResult) { _firstData.value = result } fun updateSecondData(result: SecondResult) { _secondData.value = result } fun updateThirdData(result: ThirdResult) { _thirdData.value = result } fun updateFourthData(result: FourthResult) { _fourthData.value = result } }
3. Fragment观察数据并实时展示
在Fragment中通过lifecycleScope观察ViewModel的StateFlow,收到结果后立即更新UI:
class YourFragment : Fragment() { private val viewModel: YourViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 观察第一个请求的结果 lifecycleScope.launch { viewModel.firstData.collect { result -> result?.let { // 在这里展示第一个请求的结果,比如更新TextView、RecyclerView等 } } } // 观察第二个请求的结果 lifecycleScope.launch { viewModel.secondData.collect { result -> result?.let { // 展示第二个请求的结果 } } } // 同理处理第三、第四个请求的结果 lifecycleScope.launch { viewModel.thirdData.collect { result -> result?.let { // 展示第三个请求的结果 } } } lifecycleScope.launch { viewModel.fourthData.collect { result -> result?.let { // 展示第四个请求的结果 } } } } }
异常处理补充
如果需要处理请求失败的情况,可以在每个launch协程中添加try-catch块:
launch { try { val result = repository.taskFirst() viewModel.updateFirstData(result) } catch (e: Exception) { // 处理请求异常,比如通知ViewModel展示错误提示 viewModel.updateFirstError(e.message ?: "请求失败") } }
内容的提问来源于stack exchange,提问作者testivanivan
相关产品推荐
相关产品推荐

