简体   繁体   English

Kotlin 协程:通道与流

[英]Kotlin Coroutines: Channel vs Flow

I'm recently studying and reading a lot about Flow and Kotlin Coroutines.我最近在学习和阅读很多关于Flow和 Kotlin 协程的内容。 But I still get confused about when I should use Flow and when I should use Channel .但是我仍然对什么时候应该使用Flow以及什么时候应该使用Channel感到困惑。

At the beginning it looked more simple.一开始看起来更简单。 Working with hot streams of data?使用热数据流? Channel . Channel Cold ones?冷的? Flows . Flows Same goes if you need to listen to streams of data from more than a single place;如果您需要从多个地方收听数据流,情况也是如此; if that's the case Channel is the choice to go.如果是这种情况, Channel是首选。 There are still a lot of examples and questions.还有很多例子和问题。

But recently FlowChannels where introduced, together with tons of methods and classes that encourage the use of Flow , which facilities transforming Channels into Flows and so on.但是最近引入了FlowChannels ,以及大量鼓励使用Flow的方法和类,这些方法和类有助于将Channels转换为Flows等等。 With all this new stuff coming on each Kotlin release I am getting more and more confused.随着每个 Kotlin 版本中出现所有这些新东西,我越来越困惑。 So the question is:所以问题是:

When should I use Channel and when should I use Flow ?什么时候应该使用Channel ,什么时候应该使用Flow

For many use cases where the best tool so far was Channel , Flow has become the new best tool.对于迄今为止最好的工具是Channel许多用例, Flow已成为新的最佳工具。

As a specific example, callbackFlow is now the best approach to receiving data from a 3rd-party API's callback.作为一个具体的例子, callbackFlow现在是从 3rd-party API 的回调接收数据的最佳方法。 This works especially well in a GUI setting.这在 GUI 设置中特别有效。 It couples the callback, a channel, and the associated receiving coroutine all in the same self-contained Flow instance.它将回调、通道和关联的接收协程都耦合在同一个独立的Flow实例中。 The callback is registered only while the flow is being collected.仅在收集流时注册回调。 Cancellation of the flow automatically propagates into closing the channel and deregistering the callback.取消流程会自动传播到关闭通道和取消注册回调。 You just have to provide the callback-deregistering code once.您只需要提供一次回调注销代码。

You should look at Channel as a lower-level primitive that Flow uses in its implementation.您应该将Channel视为Flow在其实现中使用的较低级别的原语。 Consider working with it directly only after you realize Flow doesn't fit your requirements.只有在您意识到Flow不符合您的要求后才考虑直接使用它。

In my opinion a great explanation is here (Roman Elizarov) Cold flows, hot channels :在我看来,这里有一个很好的解释(Roman Elizarov)冷流,热通道

Channels are a great fit to model data sources that are intrinsically hot , data sources that exist without application's requests for them: incoming network connections, event streams, etc. Channels, just like futures, are synchronization primitives.通道非常适合对本质上很热的数据源、无需应用程序请求而存在的数据源进行建模:传入网络连接、事件流等。通道,就像期货一样,是同步原语。 You shall use a channel when you need to send data from one coroutine to another coroutine in the same or in a different process当您需要将数据从一个协程发送到相同或不同进程中的另一个协程时,您应该使用通道

But what if we don't need either concurrency or synchronization, but need just non-blocking streams of data?但是如果我们不需要并发或同步,而只需要非阻塞的数据流呢? We did not have a type for that until recently, so welcome Kotlin Flow type...直到最近我们才拥有一个类型,所以欢迎 Kotlin Flow类型......

Unlike channels, flows do not inherently involve any concurrency.与通道不同,本质上不涉及任何并发性。 They are non-blocking, yet sequential.它们是非阻塞的,但是是顺序的。 The goal of flows is to become for asynchronous data streams what suspending functions are for asynchronous operations — convenient, safe, easy to learn and easy to use.流的目标是让异步数据流成为异步操作的挂起函数——方便、安全、易于学习和易于使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM