繁体   English   中英

Dart 从另一个流监听器中产生流事件

[英]Dart yield stream events from another stream listener

我有一个生成特定事件stream的函数。 现在我有一个来自存储服务的流,它有自己的事件。 寻找一种在storage stream发生变化时产生我的事件的方法。

此代码片段不起作用。

Stream<BlocState> mapEventToState(
    BlocEvent event,
  ) async* {
  if (event is UploadData) {
    yield UploadDataProgress(progress: 0.0);
    final Storage storage = Storage();
    final Stream<StorageEvent> upload = storage.upload(event.data);

    upload.listen((StorageEvent storageEvent) async* {
      print('***** Listener: ${storageEvent.type} - ${storageEvent.progress}');

      if (storageEvent.type == StorageEventType.error) {
        yield UploadDataError(errorMessage: storageEvent.error);
      }

      if (storageEvent.type == StorageEventType.success) {
        yield UploadDataSuccess();
      }

      if (storageEvent.type == StorageEventType.progress) {
        yield UploadDataProgress(progress: storageEvent.progress);
      }
    });
  }
}

输出:调试打印有效,但事件未发送到侦听器。

***** Listener: StorageEventType.progress - 0.01924033836457124
***** Listener: StorageEventType.progress - 0.044581091468101464
***** Listener: StorageEventType.progress - 0.6986233206170177
***** Listener: StorageEventType.progress - 1.0

您的yield来自匿名函数(StorageEvent storageEvent) async* {而不是来自mapEventToState

简单地用await for替换listen()应该可以工作。

Stream<BlocState> mapEventToState(
    BlocEvent event,
  ) async* {
  if (event is UploadData) {
    yield UploadDataProgress(progress: 0.0);
    final Storage storage = Storage();
    final Stream<StorageEvent> upload = storage.upload(event.data);

    await for (StorageEvent storageEvent in upload) {
      print('***** Listener: ${storageEvent.type} - ${storageEvent.progress}');

      if (storageEvent.type == StorageEventType.error) {
        yield UploadDataError(errorMessage: storageEvent.error);
      }

      if (storageEvent.type == StorageEventType.success) {
        yield UploadDataSuccess();
      }

      if (storageEvent.type == StorageEventType.progress) {
        yield UploadDataProgress(progress: storageEvent.progress);
      }
    }
  }
}

物有所值。 我有一个类似的问题,我订阅了 Firebase 快照并尝试根据文档数据产生事件。

如果我使用 await-for 范式,我将无法获得订阅句柄。 结果,当我想关闭 BLoC 时,停止读取流变得很痛苦。

我找到了一个全面的解决方案。

Stream<BlocState> mapEventToState(BlocEvent event) async* {
  if (event is FetchEvent) {
    yield LoadingState();
    _subscription = SomeStream(event.someKey).listen((snapshot) {
      add(OnSnapshotEvent(snapshot));
    });
  }

  if (event is OnSnapshotEvent) {
    if (SomeCondition(event.snapshot)) {
      yield SomeResultState();
    } else {
      yield SomeOtherState();
    }
  }
}

这样,我就有了订阅的句柄,所以我总是可以很好地清理。

暂无
暂无

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

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