返回

详解 Flutter Bloc add 两次只响应一次问题及应对方法

前端

问题

在 Flutter Bloc 中,如果连续调用两次 addEvent 方法,最终只能响应一次,第二次事件无法响应。

原因分析

出现此问题的原因在于,Bloc 的 EventStream 只会订阅一次。当第一次调用 addEvent 方法时,Bloc 会订阅 EventStream,并在接收到事件时调用对应的 EventHandler。当第二次调用 addEvent 方法时,Bloc 不会再次订阅 EventStream,因此无法接收到第二次事件。

处理方式

为了解决此问题,可以在 Bloc 的 dispose 方法中取消对 EventStream 的订阅,并在每次调用 addEvent 方法之前重新订阅 EventStream。这样,就可以确保每次调用 addEvent 方法时,Bloc 都会接收到事件。

@override
void dispose() {
  _eventStreamSubscription?.cancel();
  super.dispose();
}

@override
void addEvent(MyEvent event) {
  _eventStreamSubscription?.cancel();
  _eventStreamSubscription = _eventStream.listen((event) => _handleEvent(event));
}

注意:

  • 在实际使用中,应该根据具体情况来决定是否需要在每次调用 addEvent 方法之前取消对 EventStream 的订阅。如果 Bloc 的 EventStream 不会经常被调用,则可以不取消订阅,以避免额外的开销。

  • 如果需要在 Bloc 中处理多个事件流,则可以使用 MergeStream 来合并多个流,并使用一个 EventStreamSubscription 来订阅合并后的流。

示例

final _eventStream1 = Stream<MyEvent1>.fromIterable([MyEvent1()]);
final _eventStream2 = Stream<MyEvent2>.fromIterable([MyEvent2()]);

final _mergedEventStream = MergeStream([_eventStream1, _eventStream2]);

@override
void dispose() {
  _eventStreamSubscription?.cancel();
  super.dispose();
}

@override
void addEvent(MyEvent event) {
  _eventStreamSubscription?.cancel();
  _eventStreamSubscription = _mergedEventStream.listen((event) => _handleEvent(event));
}

总结

在 Flutter Bloc 中,连续调用两次 addEvent 方法时,最终只能响应一次,第二次事件无法响应。这是因为 Bloc 的 EventStream 只会订阅一次。为了解决此问题,可以在 Bloc 的 dispose 方法中取消对 EventStream 的订阅,并在每次调用 addEvent 方法之前重新订阅 EventStream。