收集内部流时取消协程

Coroutine canceled when the inner flow is collected

在这段代码中,好像是协程遇到一个流收集的时候就取消了。

fun main() = runBlocking {
    println("Hi, world!")
    CoroutineScope(Dispatchers.Default).launch {
        innerSuspend()
        println("Bye, world!")
    }.join()
    println("task ended.")
}

suspend fun innerSuspend() {
    println("run: innerSuspend")
    innerFlow().collect {
        println("innerCallback : $it")
    }
}

suspend fun innerFlow() = callbackFlow {
    trySend("U r world?")
    awaitClose { close() }
}

我希望上面代码的结果看起来像这样:

Hi, world!
run: innerSuspend
innerCallback : U r world?
Bye, world!
task ended.

但是,事与愿违,Bye, world!没有显示。

Hi, world!
run: innerSuspend
innerCallback : U r world?

为什么会发生这种情况,我该如何解决?

你的协程没有被取消。它仍然处于暂停状态,等待 Flow 中的下一个项目。您设计了一个永不关闭的流程,因此对其调用 collect() 将永远暂停。

你把close()的调用放在awaitClose { }里面,就好像你只想在它已经关闭之后再关闭一样,这是没有意义的。你应该只输入 close().

suspend fun innerFlow() = callbackFlow {
    trySend("U r world?")
    close()
}