Flutter 中的异步事件处理之Stream源码解析(一)

基本概念

Flutter 中的 Stream(流)是一个用于异步事件处理的重要概念,它允许你在应用程序中传递和监听数据的变化。Stream 通常与 StreamController 一起使用,StreamController 用于管理流的数据并将数据推送给监听者。

Sink

csharp 复制代码
/// A generic destination for data.
///
/// Multiple data values can be put into a sink, and when no more data is
/// available, the sink should be closed.
///
/// This is a generic interface that other data receivers can implement.
abstract class Sink<T> {}

根据官方文档解释:

  • 抽象类 Sink<T> 表示一个数据接收器,用于接收泛型类型 T 的数据。
  • 抽象类是不能被直接实例化的,而是需要被其他类继承或实现。

add

csharp 复制代码
abstract class Sink<T> {
  /// Adds [data] to the sink.
  ///
  /// Must not be called after a call to [close].
  void add(T data);
}

这是一个抽象方法,用于将数据添加到接收器中。开发者需要在实现这个接口时提供方法的具体实现。它要求传入一个类型为 T 的数据,将其添加到接收器中。

close

csharp 复制代码
abstract class Sink<T> {
  /// Closes the sink.
  ///
  /// The [add] method must not be called after this method.
  ///
  /// Calling this method more than once is allowed, but does nothing.
  void close();
}

这是另一个抽象方法,用于关闭接收器。关闭接收器表示不再接受新的数据。与 add 方法一样,开发者需要在实现时提供具体的关闭逻辑。同时,根据接收器的实现,可能允许多次调用 close 方法,但多次调用什么也不做。

EventSink

csharp 复制代码
/// A [Sink] that supports adding errors.
///
/// This makes it suitable for capturing the results of asynchronous
/// computations, which can complete with a value or an error.
///
/// The [EventSink] has been designed to handle asynchronous events from
/// [Stream]s. See, for example, [Stream.eventTransformed] which uses
/// `EventSink`s to transform events.
abstract class EventSink<T> implements Sink<T> {}

EventSink 是一个抽象类,它实现了 Sink<T> 接口,表示它是一个数据接收器。它用于处理异步计算的结果,这些计算可能产生值或错误。它通过泛型参数 T 来指定可以接收的数据类型,与前面提到的 Sink<T> 相似。

EventSink<T> 是一个用于处理异步事件的接口,它可以接收数据事件和错误事件,并提供关闭接收器的方法。这种设计非常适用于处理异步计算的结果,例如处理来自 Stream 的异步事件。

add

csharp 复制代码
abstract class EventSink<T> implements Sink<T> {
  /// Adds a data [event] to the sink.
  ///
  /// Must not be called on a closed sink.
  void add(T event);
}

这是一个方法,用于向接收器添加数据事件 event。与普通的 Sink 接口相同,它要求传入类型为 T 的数据事件,并将其添加到接收器中。但是,请注意,这里使用了术语 "event" 而不是 "data",因为这个接口主要用于处理异步事件。

addError

csharp 复制代码
abstract class EventSink<T> implements Sink<T> {
  /// Adds an [error] to the sink.
  ///
  /// Must not be called on a closed sink.
  void addError(Object error, [StackTrace? stackTrace]);
}

这是另一个方法,用于向接收器添加错误信息。它允许你将一个错误对象 error 添加到接收器中,还可以选择性地传递与错误相关的堆栈信息 stackTrace。这对于捕获异步计算的错误非常有用。

close

csharp 复制代码
abstract class EventSink<T> implements Sink<T> {
  /// Closes the sink.
  ///
  /// Calling this method more than once is allowed, but does nothing.
  ///
  /// Neither [add] nor [addError] must be called after this method.
  void close();
}

与普通的 Sink 接口一样,这个方法用于关闭接收器,表示不再接受新的数据。与之前提到的 Sink 不同的是,它还可以处理错误事件。

StreamSink

csharp 复制代码
/// A object that accepts stream events both synchronously and asynchronously.
///
/// A [StreamSink] combines the methods from [StreamConsumer] and [EventSink].
///
/// The [EventSink] methods can't be used while the [addStream] is called.
/// As soon as the [addStream]'s [Future] completes with a value, the
/// [EventSink] methods can be used again.
///
/// If [addStream] is called after any of the [EventSink] methods, it'll
/// be delayed until the underlying system has consumed the data added by the
/// [EventSink] methods.
///
/// When [EventSink] methods are used, the [done] [Future] can be used to
/// catch any errors.
///
/// When [close] is called, it will return the [done] [Future].
abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {}
  • 定义了一个抽象类 StreamSink<S>,它表示一个对象,可以同时接收同步和异步的流事件
  • StreamSink 组合了 StreamConsumerEventSink 的方法。
  • 它提供了关闭接收器和处理完成的功能。这对于处理数据流非常有用。
  • 异步和同步事件的处理:StreamSink 允许你同时处理同步事件和异步事件。EventSink 方法在调用 addStream 方法期间无法使用,但一旦 addStream 方法的 Future 完成并返回,就可以再次使用这些方法。

close

csharp 复制代码
abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
  /// Tells the stream sink that no further streams will be added.
  ///
  /// This allows the stream sink to complete any remaining work and release
  /// resources that are no longer needed
  ///
  /// Returns a future which is completed when the stream sink has shut down.
  /// If cleaning up can fail, the error may be reported in the returned future,
  /// otherwise it completes with `null`.
  ///
  /// Returns the same future as [done].
  ///
  /// The stream sink may close before the [close] method is called, either due
  /// to an error or because it is itself providing events to someone who has
  /// stopped listening. In that case, the [done] future is completed first,
  /// and the `close` method will return the `done` future when called.
  ///
  /// Unifies [StreamConsumer.close] and [EventSink.close] which both mark their
  /// object as not expecting any further events.
  Future close();
}

这是一个方法,用于告诉流事件接收器,不会再添加更多的流。这允许流事件接收器完成任何剩余的工作并释放不再需要的资源。该方法返回一个 Future,该 Future 在流事件接收器关闭时完成。如果关闭过程中发生错误,错误可能会在返回的 Future 中报告。

done

csharp 复制代码
abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {

  /// Return a future which is completed when the [StreamSink] is finished.
  ///
  /// If the `StreamSink` fails with an error,
  /// perhaps in response to adding events using [add], [addError] or [close],
  /// the [done] future will complete with that error.
  ///
  /// Otherwise, the returned future will complete when either:
  ///
  /// * all events have been processed and the sink has been closed, or
  /// * the sink has otherwise been stopped from handling more events
  ///   (for example by canceling a stream subscription).
  Future get done;
}

这是一个属性,它返回一个 Future,该 Future 在流事件接收器完成时完成。如果流事件接收器失败并导致错误(例如通过 addaddErrorclose 添加事件时出错),则 doneFuture 将以该错误完成。否则,doneFuture 将在以下情况之一完成:

  • 所有事件都已处理并且接收器已关闭。
  • 接收器已停止处理更多事件(例如,取消了流订阅)。

StreamController

csharp 复制代码
abstract class StreamController<T> implements StreamSink<T> {}

定义了一个抽象类,表示一个数据流控制器。它通过泛型参数 T 来指定可以处理的事件的类型。这个控制器允许向它的 stream 发送数据、错误和完成事件。

总结

他们从SinkStreamSink都只是到导入接口,并无直接继承关系,在抽象类方面按照功能解耦,最终由StreamController整合,负责添加的是StreamControlelr,负责监听的是Stream,最终在当前的Zone中执行回调Zone.runUnaryGuarded()Zone类似一个沙盒环境,在APP启动的时候创建。

相关推荐
余生H4 分钟前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍7 分钟前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai11 分钟前
网站开发的发展(后端路由/前后端分离/前端路由)
前端
流烟默23 分钟前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch
2401_8572979133 分钟前
招联金融2025校招内推
java·前端·算法·金融·求职招聘
茶卡盐佑星_44 分钟前
meta标签作用/SEO优化
前端·javascript·html
Ink1 小时前
从底层看 path.resolve 实现
前端·node.js
金灰1 小时前
HTML5--裸体回顾
java·开发语言·前端·javascript·html·html5
茶卡盐佑星_1 小时前
说说你对es6中promise的理解?
前端·ecmascript·es6
Promise5201 小时前
总结汇总小工具
前端·javascript