【发布时间】:2022-02-08 23:57:34
【问题描述】:
我有以下代码的更复杂版本:
val testFlow = flow {
try {
// Continually emit some values
} catch (e: CancellationException) {
// Wrap up and emit finished state value
}
}
当我收集这个 testFlow 时,我从来没有收到完成的状态值。 documented 是流构建器在发出值之前执行 ensureActive 检查。在此链接中还有一个使用 IntRange.asFlow 的示例,它在发出值之前不检查取消并显示这些值会继续被收集。
有没有办法让自定义 kotlin 流在取消协程后发出最后一个要收集的值?
这是一个Kotlin Playground example(感谢@Tenfour04),它显示了根据流程的构造方式,取消后发出的不同行为。我只是不知道如何获得一个能够在取消后发出的不是由IntRange.asFlow 构造的流。
【问题讨论】:
-
如果存在 CancellationException,则不能发出,因为这意味着不再收集流。
-
感谢您的评论。 IntRange.asFlow 例子表明协程取消后似乎有办法继续收集。你能详细说明我的误解在哪里吗?
-
我在该页面上没有看到任何示例。有一些在取消后记录某些内容但不发出任何内容的示例。当协程被取消时,它将在第一次机会时停止所有执行(任何挂起函数调用),因此即使您的 Flow 上的
onCompletion运算符中有代码,onCompletion块也只会执行代码到它调用的第一个挂起函数。 -
你看过我给出的操场例子了吗? IntRange testFlow 继续发出值 4 和 5,即使在收集值 3 时取消了协程。如果我理解正确,流取消是合作的,并且 IntRange 示例不会立即合作取消自身,即使它似乎仍在发出值(至少隐含地)。不好意思一再问。我似乎没有理解 IntRange 示例和使用
flow {}builder 的自定义流程之间的技术差异。 -
好的,我看了看,我很困惑。
IntRange.asFlow()似乎不配合取消,即使您查看实现,它使用flow构建器和emit,如果您直接重新构建相同的代码,它确实 合作!见这里:pl.kotl.in/KvFli_h59
标签: kotlin cancellation kotlin-flow