侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

实现并发网络请求并处理结果聚合

2025-12-12 / 0 评论 / 4 阅读

题目

实现并发网络请求并处理结果聚合

信息

  • 类型:问答
  • 难度:⭐⭐

考点

结构化并发, async/await模式, 异常处理, 协程作用域管理

快速回答

实现要点:

  • 使用coroutineScope创建结构化并发作用域
  • 通过async启动并发任务
  • 使用awaitAll()等待所有结果
  • 异常处理需结合try-catchCoroutineExceptionHandler
  • 避免使用GlobalScope防止内存泄漏
## 解析

场景需求

需要并发请求三个API接口(用户数据/订单数据/商品数据),聚合结果后统一处理,任一请求失败需取消其他请求并返回错误信息。

核心实现代码

suspend fun fetchCombinedData(): Result<CombinedData> = coroutineScope {
    val userDeferred = async { fetchUserData() }
    val orderDeferred = async { fetchOrderData() }
    val productDeferred = async { fetchProductData() }

    try {
        val results = awaitAll(userDeferred, orderDeferred, productDeferred)
        Result.success(combineResults(results))
    } catch (e: Exception) {
        Result.failure(e)
    }
}

// 实际网络请求函数(模拟)
suspend fun fetchUserData(): UserData {
    delay(1000)
    return UserData() // 实际应使用Retrofit等网络库
}

原理说明

  • 结构化并发coroutineScope创建的子作用域会等待所有子协程完成,任一子协程失败将自动取消其他子协程
  • async/await模式async启动并发任务返回Deferred对象,await()获取结果
  • 异常传播:子协程异常会传播到父协程,触发作用域内取消

最佳实践

  • 作用域管理:使用viewModelScopelifecycleScope避免内存泄漏
  • 错误处理
    val handler = CoroutineExceptionHandler { _, e ->
        // 统一处理未捕获异常
    }
    viewModelScope.launch(handler) { ... }
  • 超时控制:使用withTimeout(3000)设置全局超时

常见错误

  • 错误1:忘记调用await()导致并发失效
  • 错误2:使用GlobalScope引发内存泄漏
  • 错误3:在async块外捕获异常导致崩溃
  • 错误4:未处理CancellationException干扰协程取消

扩展知识

  • 结果聚合优化:使用listOf(deferred1, deferred2).awaitAll()
  • 部分成功处理
    val results = listOf(userDeferred, orderDeferred)
        .map { deferred ->
            runCatching { deferred.await() }
        }
  • 性能考量:超过5个并发请求建议使用Dispatchers.IO.limitedParallelism(5)限制线程数