Kotlin推论:渠道与流量



我最近学习并阅读了很多关于Flow和Kotlin推论的内容。但我仍然对什么时候应该使用Flow和什么时候应该用Channel感到困惑。

一开始它看起来更简单。使用热数据流?Channel。冷的?Flows。如果你需要监听来自多个地方的数据流,也是如此;如果是这种情况,CCD_ 5是选择。还有很多例子和问题。

但最近推出了FlowChannels,以及大量鼓励使用Flow的方法和类,这些方法和类有助于将Channels转换为Flows等等。所以问题是:

我应该什么时候使用通道,什么时候应该使用Flow

对于许多迄今为止最好的工具是Channel的用例,Flow已成为新的最佳工具。

作为一个具体的例子,callbackFlow现在是从第三方API的回调接收数据的最佳方法。这在GUI设置中尤其适用。它将回调、通道和相关的接收协同程序耦合在同一个自包含的Flow实例中。只有在收集流时才会注册回调。流的取消会自动传播到关闭通道和取消注册回调。您只需要提供一次回调注销代码。

您应该将Channel视为Flow在其实现中使用的较低级别原语。只有在意识到Flow不符合您的要求后,才考虑直接使用它。

在我看来,这里有一个很好的解释(Roman Elizarov)冷流,热通道:

通道非常适合对本质上很热的数据源、存在时没有应用程序请求的数据源进行建模:传入网络连接、事件流等。通道和期货一样,都是同步原语。当你需要在相同或不同的过程中将数据从一个协程发送到另一个协程时,你应该使用一个通道

但是,如果我们不需要并发或同步,而只需要非阻塞的数据流,该怎么办?直到最近,我们才有这样的类型,所以欢迎KotlinFlow类型。。。

与通道不同,本质上不涉及任何并发。它们是非阻塞的,但却是连续的。流的目标是使异步数据流成为异步操作的挂起函数——方便、安全、易于学习和使用。

将流视为数据流,将通道视为队列。流都是关于处理可能不会停止的连续数据流。它们非常适合数据不断进入的场景,如监测传感器读数或实时用户交互。

另一方面,通道的工作方式类似于一个队列,您可以将数据一个接一个地放入和取出。然而,通过通道发送的每个事件都由一个订阅者消耗,这与Flows不同,在Flows中,每个发射都在所有收集器之间共享。这种行为是渠道基本设计的一部分,通常被称为"单一消费者"语义。它确保数据的顺序和流得到维护,并且每条数据都由单个协程或使用者处理。在您希望保证数据按特定顺序处理的情况下,或者在您希望避免多个消费者同时访问同一数据时可能出现的竞争情况下,此特性尤其有用。当您有一个消费者(协同程序)需要以可控的方式接收数据时,通道尤其有用,可以确保每条数据只使用一次。

当多个消费者积极消费来自一个渠道的数据时,渠道的行为是以顺序的方式轮流向每个消费者交付数据。这确保了没有消费者占用所有数据,并且所有消费者都有机会处理他们接收到的数据。这种公平分配机制在多个消费者同时工作并且希望防止任何一个消费者垄断数据处理的情况下特别有用。它可以促进资源的均衡利用,并防止应用程序中出现潜在的瓶颈。流具有内置的背压处理功能,当数据输入过快时,它可以帮助您管理数据。通道没有这个内置功能,所以在使用通道时需要手动处理背压。

参考:https://androidlearnersite.wordpress.com/2023/08/09/kotlin-flows-part-4/

最新更新