首页 > 解决方案 > 收集内部流时取消协程

问题描述

在这段代码中,当协程遇到一个收集的流时,它似乎被取消了。

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() }
}

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

你好世界!
运行:innerSuspend
innerCallback :你的世界?
再见,世界!
任务结束。

但是,出乎意料的是,Bye, world!它没有显示出来。

你好世界!
运行:innerSuspend
innerCallback :你的世界?

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

标签: kotlinkotlin-coroutinescoroutineflow

解决方案


你的协程没有被取消。它仍然处于暂停状态,等待您的 Flow 中的下一个项目。你设计了一个永不关闭的 Flow,所以调用collect()它会永远挂起。

你把close()调用放在里面awaitClose { },好像你只希望它在它已经关闭后才关闭,这没有意义。你应该把close().

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

推荐阅读