将suspendCancellableCoroutine转为callbackFlow及重复调用报错解决
问题原因分析
你用suspendCancellableCoroutine实现的函数报错,核心原因是**continuation.resume()只能调用一次**,但你的Callback可能被多次触发(比如重复调用result()时未清理旧的callback,或者每次调用都注册新callback导致重复回调),多次尝试resume同一个continuation就会抛出"Already resumed"异常。
正确的callbackFlow实现及调用方式
1. 修正result()函数
用callbackFlow时,必须在流关闭时注销callback,避免内存泄漏和重复回调:
suspend fun result() = callbackFlow<Int> { val callback = object : Callback { override fun onResult(value: Int) { // 用trySend发送结果,适配callback可能运行在非协程线程的场景 trySend(value).run { if (!isSuccess) { // 可选:处理发送失败(比如流已关闭) } } } } // 注册callback到你的目标服务/SDK someApi.registerCallback(callback) // awaitClose会在流结束时执行,这里务必注销callback awaitClose { someApi.unregisterCallback(callback) } }
2. 协程中调用的两种场景
场景1:只需要单次结果(和原代码行为一致)
用first()获取第一个回调结果后自动关闭流,同时注销callback:
someCoroutine { val result = result().first() when(result) { x -> doSomething() y -> doSomethingElse() // ...其他分支 } }
场景2:需要接收多次回调结果
用collect()持续监听回调,直到流被取消或主动关闭:
someCoroutine { result().collect { value -> when(value) { x -> doSomething() y -> doSomethingElse() // ...其他分支 } } // collect是挂起函数,会一直阻塞直到流关闭 }
内容的提问来源于stack exchange,提问作者pop
相关产品推荐
相关产品推荐

