【问题标题】:Best practice to use mapEventToState with incoming streams?将 mapEventToState 与传入流一起使用的最佳实践?
【发布时间】:2020-03-21 18:56:25
【问题描述】:

是否有任何优雅的方法可以直接在 mapEventToState() 内部映射来自私有 api 的传入流,而无需在 bloc 中创建冗余私有事件?

我带来了这个解决方案。单个流没问题,但是多个流开始变得一团糟。提前致谢。

// (don't mind the imports, this is the bloc file)

class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {


  final MyPrivateApi api = MyPrivateApi.instance; // singleton

  ExampleBloc() {
    // api has a stream of booleans
    api.myStream.listen((b) {
    // if it's true fire this event
    if (b) this.add(_MyPrivateEvent());
  }

  @override
  ExampleState get initialState => InitialExampleState();

  @override
  Stream<ExampleState> mapEventToState(
    ExampleEvent event,
  ) async* {
    if (event is _MyPrivateEvent) {
      yield SomeState;
    }
  }



// private Event
class _MyPrivateEvent extends ExampleEvent {

}

【问题讨论】:

    标签: flutter design-patterns bloc


    【解决方案1】:

    构建另一个封装字节流的块。

    您可以创建两个事件(ByteReadByteConsume)和两个状态(ByteWaitingByteAvailable)。

    BytereadByteAvailable 应该有一个 _byte 字段用于存储数据。您的 bytebloc 有一个订阅者正在监听流,并且每次它读取一个字节时都会触发一个 ByteRead 事件。

    您还应该向 bloc 添加一个 consume() 方法,该方法给出读取的最后一个字节并触发 ByteConsume 事件。

    这两种状态和事件是相互的:

    • 您从 bytewaiting 开始,每次有 ByteRead 时,您都会更改为 ByteAvailable
    • 每次您有 ByteConsume 时,您都会更改回 ByteWaiting

    【讨论】:

      【解决方案2】:

      您的方式似乎是唯一可行且似乎已被使用的方式 - 请参阅此集团问题:https://github.com/felangel/bloc/issues/112 和此示例项目:https://github.com/algirdasmac/streams_and_blocs

      只需确保dispose 得到api.myStream.listen 返回的订阅。

      上一个答案

      以下适用于无限流,因为生成器函数将await 直到流结束。这只能用于快速流式传输,例如上传/下载进度。 在此处查看已接受的答案 Dart yield stream events from another stream listener 和此处 Dart/Flutter - "yield" inside a callback function

        ExampleBloc() {
          _MyInitEvent();
        }
      
        @override
        Stream<ExampleState> mapEventToState(
          ExampleEvent event,
        ) async* {
          if (event is _MyInitEvent) {
            await for (bool b in api.myStream) {
              if (b) yield SomeState;
            }
          }
        }
      

      【讨论】:

      • 我认为它不起作用,因为流不是有限的,并且在 yield 函数上使用它会停止即将发生的事件,直到等待流关闭。
      • 是的,你是对的,我想没有别的办法了。我正在考虑在下一个项目中使用 bloc,但这是一个巨大的障碍。
      【解决方案3】:

      如我所见,您可以在屏幕上订阅事件更新,并在需要计算时将事件从屏幕推送到 Bloc。代码会更干净。

      【讨论】:

      • 问题是我无法订阅 mapEventToState() 中的流,这迫使我必须拥有私有事件才能产生状态
      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 2022-06-22
      • 1970-01-01
      • 2021-03-07
      相关资源
      最近更新 更多