mcpField
K
kotlin-coroutines-expert

kotlin-coroutines-expert

github.com/sickn33开发48.7k77 次安装今天更新
代码仓库

关于 kotlin-coroutines-expert

面向 Kotlin 开发者的协程指南,涵盖异步编程、结构化并发、Flow、异常处理与测试,并提供取消和错误排查建议。

主要功能

  1. 01结构化并发指导
  2. 02Flow 转换与流模式
  3. 03协程异常处理
  4. 04使用 TestScope 和 runTest 测试

适用场景

  1. 01实现 Kotlin 异步操作
  2. 02设计 Flow 响应式数据流
  3. 03排查取消与异常问题
  4. 04测试挂起函数和 Flow

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill kotlin-coroutines-expert

安装后在 Claude Code 中输入/kotlin-coroutines-expert确认已加载。

详细介绍

Kotlin Coroutines 专家

概述

掌握使用 Kotlin Coroutines 进行异步编程的指南。涵盖结构化并发、Flow 转换、异常处理和测试策略等高级主题。

何时使用此技能

  • 在 Kotlin 中实现异步操作时使用。
  • 使用 Flow 设计响应式数据流时使用。
  • 调试协程取消或异常时使用。
  • 为挂起函数或 Flows 编写单元测试时使用。

分步指南

1. 结构化并发

始终在明确的 CoroutineScope 中启动协程。使用 coroutineScope 或 supervisorScope 将并发任务分组。

suspend fun loadDashboardData(): DashboardData = coroutineScope {
    val userDeferred = async { userRepo.getUser() }
    val settingsDeferred = async { settingsRepo.getSettings() }

    DashboardData(
        user = userDeferred.await(),
        settings = settingsDeferred.await()
    )
}
2. 异常处理

顶层作用域使用 CoroutineExceptionHandler,但在挂起函数中依靠 try-catch 进行细粒度控制。

val handler = CoroutineExceptionHandler { _, exception ->
    println("Caught $exception")
}

viewModelScope.launch(handler) {
    try {
        riskyOperation()
    } catch (e: IOException) {
        // Handle network error specifically
    }
}
3. 使用 Flow 构建响应式流

需要保留状态时使用 StateFlow,事件则使用 SharedFlow。

// Cold Flow (Lazy)
val searchResults: Flow<List<Item>> = searchQuery
    .debounce(300)
    .flatMapLatest { query -> searchRepo.search(query) }
    .flowOn(Dispatchers.IO)

// Hot Flow (State)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()

示例

示例 1:带错误处理的并行执行
suspend fun fetchDataWithErrorHandling() = supervisorScope {
    val task1 = async {
        try { api.fetchA() } catch (e: CancellationException) { throw e } catch (e: IOException) { null }
    }
    val task2 = async { api.fetchB() }

    // A child failure does not directly cancel its siblings.
    // But an uncaught exception from await escapes the supervisor block and cancels it.
    val result1 = task1.await()
    val result2 = task2.await() // May throw
}

最佳实践

  • ✅ 应该: 对阻塞式 I/O 操作使用 Dispatchers.IO。
  • ✅ 应该: 不再需要作用域时取消它(例如,在 ViewModel.onCleared 中)。
  • ✅ 应该: 使用 TestScope 和 runTest 对协程进行单元测试。
  • ❌ 不应该: 使用 GlobalScope。它会破坏结构化并发,并可能导致资源泄漏。
  • ❌ 不应该: 捕获 CancellationException,除非随后将其重新抛出。

故障排除

问题: 协程测试挂起或出现不可预测的失败。 解决方案: 确保使用 runTest,并向类注入 TestDispatcher,以便控制虚拟时间。

限制

  • 仅当任务明确符合上述范围时才使用此技能。
  • 不要将输出视为环境特定验证、测试或专家审查的替代品。
  • 如果缺少必需的输入、权限、安全边界或成功标准,请暂停并请求澄清。

示例均为片段:请补充导入、仓库接口、Android 生命周期依赖项以及已安装的 coroutines 版本。谨慎处理每个挂起调用的失败,并重新抛出取消异常。没有活跃收集器时,SharedFlow 的重放和缓冲选项会影响事件传递;它并非有保证的事件队列。StateFlow 会合并状态变化。测试取消以及收集器缓慢或缺失的情况,而不应只测试顺利路径。官方异常行为说明。

评论

支持 Markdown