如何取消 Cubit 内的 StreamSubscription?

How do I cancel a StreamSubscription inside a Cubit?

我有一个 cubit 监听消息流,并发出一个保存消息的状态。 在屏幕上,我使用 BlocProvider 来访问 cubit,并使用 BlocBuilder 来显示 消息。

在以下情况下,我是否需要关闭在 listen() 上创建的 StreamSubscription?有干净的方法吗?

class MessageCubit extends Cubit<MessageState> {
  final GetMessagesUseCase getMessagesUseCase;
  MessageCubit({this.getMessagesUseCase}) : super(MessageInitial());
  Future<void> getMessages({String senderId, String recipientId}) async {
    emit(MessageLoading());
    try {
      final messagesStreamData = getMessagesUseCase.call();

      //This is where I listen to a stream
      messagesStreamData.listen((messages) {
        emit(MessageLoaded(messages: messages));
      });


    } on SocketException catch (_) {
      emit(MessageFailure());
    } catch (_) {
      emit(MessageFailure());
    }
  }
}

不需要关闭订阅,但您应该作为良好做法避免潜在的内存泄漏。既然如此简单,就没有任何牺牲。

  1. 创建 StreamSubscription<your type> 类型的 class 变量。假设它被命名为 sub.
  2. 在收听之前的 getMessages 中:await sub?.cancel()
  3. 然后sub = messagesStreamData.listen(...
  4. 覆盖 Cubit 的 close 方法和 运行 与项目符号 2 中相同的命令。

完整代码:

class MessageCubit extends Cubit<MessageState> {
  final GetMessagesUseCase getMessagesUseCase;

  // Added
  StreamSubscription<YOUR_MESSAGES_TYPE> sub;

  MessageCubit({this.getMessagesUseCase}) : super(MessageInitial());
  Future<void> getMessages({String senderId, String recipientId}) async {
    emit(MessageLoading());
    try {
      final messagesStreamData = getMessagesUseCase.call();

      // Added
      await sub?.cancel();
      //This is where I listen to a stream
      sub = messagesStreamData.listen((messages) {
        emit(MessageLoaded(messages: messages));
      });


    } on SocketException catch (_) {
      emit(MessageFailure());
    } catch (_) {
      emit(MessageFailure());
    }
  }

  // Added    
  @override
  Future<void> close() async {
    await sub?.cancel();
    return super.close();
  }
}