在 BLoC 模式中,当监听的回调被多次调用时,可以采取以下解决方法:
StreamSubscription
对象来监听数据流,并在不需要时取消订阅。通过取消订阅可以避免多次调用回调函数。class MyBloc {
StreamController _controller = StreamController();
Stream get stream => _controller.stream;
void fetchData() {
// 模拟异步请求数据
Future.delayed(Duration(seconds: 1), () {
_controller.sink.add(42); // 添加数据到流中
});
}
void dispose() {
_controller.close(); // 关闭流
}
}
void main() {
MyBloc bloc = MyBloc();
StreamSubscription? subscription;
void onData(int data) {
print(data);
}
subscription = bloc.stream.listen(onData); // 订阅流
bloc.fetchData(); // 调用异步方法获取数据
// 等待异步请求完成
Future.delayed(Duration(seconds: 2), () {
subscription?.cancel(); // 取消订阅
bloc.dispose(); // 销毁 BLoC
});
}
在上面的代码中,我们使用 StreamSubscription
对象 subscription
来订阅数据流。当数据流发出新的值时,回调函数 onData
将被调用。在最后,我们通过 subscription.cancel()
取消订阅,并在 bloc.dispose()
中关闭流,以避免资源泄漏。
BehaviorSubject
:BehaviorSubject
是 rxdart
库中的一个类,它可以保存最新的数据并在有新的订阅时立即发送给订阅者。使用 BehaviorSubject
可以确保订阅者只会收到最新的数据,而不会被之前的重复数据触发。import 'package:rxdart/rxdart.dart';
class MyBloc {
BehaviorSubject _subject = BehaviorSubject.seeded(0);
Stream get stream => _subject.stream;
void fetchData() {
// 模拟异步请求数据
Future.delayed(Duration(seconds: 1), () {
_subject.add(42); // 添加数据到流中
});
}
void dispose() {
_subject.close(); // 关闭流
}
}
void main() {
MyBloc bloc = MyBloc();
StreamSubscription? subscription;
void onData(int data) {
print(data);
}
subscription = bloc.stream.listen(onData); // 订阅流
bloc.fetchData(); // 调用异步方法获取数据
// 等待异步请求完成
Future.delayed(Duration(seconds: 2), () {
subscription?.cancel(); // 取消订阅
bloc.dispose(); // 销毁 BLoC
});
}
在上面的代码中,我们使用 BehaviorSubject
对象 _subject
来创建一个数据流。在 fetchData
方法中,我们使用 _subject.add()
添加数据到流中。当有新的订阅者时,BehaviorSubject
会立即发送最新的数据。通过使用 BehaviorSubject
,我们可以确保每个订阅者只会收到最新的数据,从而避免重复调用回调函数。
以上是两种解决 BLoC 中监听回调被多次调用的方法,你可以根据具体情况选择适合的解决方案。
上一篇:Bloc、Flutter和导航
下一篇:BLoC:如何传递它?