如何使用Retrofit发起多POST请求并接收响应校验提交状态?
批量POST请求的最佳实现方案
核心优化方向
- 并发执行请求:避免串行请求拖慢效率,用协程并发处理同时控制请求数量,防止服务器过载
- 保留请求关联信息:不要只返回布尔值,返回包含原数据和结果的对象,方便定位成功/失败的具体项
- 完善异常处理:单个请求失败不中断整体流程,捕获异常并标记为失败
- 优化流的构建逻辑:避免嵌套
collect的冗余写法,用更简洁的Flow操作符处理数据
优化后的代码示例
首先定义承载结果的数据类,关联原数据与提交状态:
data class WeightSubmitResult( val weight: Weight, // 替换为你的Weight实体类 val isSuccess: Boolean, val errorMessage: String? = null )
然后实现批量提交函数:
private suspend fun submitConfirmWeights(): Flow<WeightSubmitResult> = flow { // 获取离线数据集合(如果是持续发射的Flow,可改用first()获取当前快照) val offlineWeights = syncRepositoryImpl.getOfflineShopCollections().first() coroutineScope { // 并发执行请求,默认使用Dispatcher.IO的并发限制 val deferredResults = offlineWeights.map { weight -> async { runCatching { val dto = confirmWeightsDtoMapper.mapFromDomainModel(weight) val response = confirmWeightsService.confirmWeights(dto) // 判断请求成功且业务状态正常 response.isSuccessful && response.body()?.status == true }.fold( onSuccess = { isSuccess -> WeightSubmitResult(weight, isSuccess) }, onFailure = { error -> WeightSubmitResult(weight, false, error.localizedMessage) } ) } } // 等待所有请求完成,逐个发射结果 deferredResults.forEach { deferred -> emit(deferred.await()) } } }
关键细节补充
- 自定义并发数:如果需要限制同时发起的请求数(比如最多5个),可以用信号量控制:
val semaphore = Semaphore(5) // 在async内部添加许可控制 async { semaphore.withPermit { // 执行请求逻辑 } } - 响应实时数据更新:如果
getOfflineShopCollections()是监听数据库变化的Flow,可改用flatMapConcat响应新数据:private fun submitConfirmWeights(): Flow<WeightSubmitResult> = syncRepositoryImpl.getOfflineShopCollections() .flatMapConcat { weights -> flow { // 内部执行上述并发请求逻辑 } } - 结果处理示例:调用方可以精准处理成功/失败项:
viewModelScope.launch { submitConfirmWeights().collect { result -> if (result.isSuccess) { // 成功逻辑:比如从离线库删除该数据 syncRepositoryImpl.removeOfflineWeight(result.weight) } else { // 失败逻辑:比如记录错误或标记待重试 Log.e("Submit", "提交失败[${result.weight.id}]: ${result.errorMessage}") } } }
原代码的问题分析
- 串行执行效率低:
forEach逐个同步发起请求,批量数据多时耗时过长 - 结果无关联:仅发射布尔值,无法对应到具体的Weight数据,后续无法精准处理
- 异常无防护:单个请求抛出异常会中断整个Flow,导致后续请求无法执行
- Flow嵌套冗余:在
flow内部调用collect,流的生命周期管理复杂,不如直接用Flow操作符简洁
内容的提问来源于stack exchange,提问作者ismail M
相关产品推荐
相关产品推荐

