让我们考虑一下这种情况:
class Repository {
final _controller = Behaviorsubject<List<Object>>();
Stream<List<Object>> get stream => _controller.stream;
void fetchObjects() async {
final response = await _dataService.getObjects();
final objects = _convertResponseToObjects();
_controller.add(objects);
}
}
class ObjectsBloc extends Bloc {
ObjectsBloc(this._repository) : super(Status.initial) {
_init();
}
final Repository _repository;
void _init() {
on<ObjectsFetched>((event, emit) {
emit(state.copyWith(status: Status.waiting));
await emit.forEach<List<Object>>(
_repository.stream,
onData: (objects) => state.copyWith(
status: Status.success,
objects: objects,
),
onError: (error, _) => state.copyWith(
status: Status.failure,
error: error,
),
);
});
add(const ObjectFetched());
}
}
class ObjectsCubit extends Cubit {
ObjectsCubit(this._repository) : super(Status.initial) {
_init();
}
final Repository _repository;
void _init() {
_repository.stream.listen((objects) {
emit(state.copyWith(
status: Status.success,
objects: objects,
));
}, onError: (error, _) {
emit(state.copyWith(
status: Status.failure,
error: error,
));
});
}
void fetchEntities() {
emit(state.copyWith(status: Status.waiting));
_repositoy.fetchEntities();
}
}
当前 ObjectsBloc
和 ObjectsCubit
的功能是否等效?在 ObjectsBloc
中使用 await eager.forEach
而不是在 ObjectsCubit
中使用 _repository.stream.listen
有什么好处吗?处理Status.success
?
最佳答案
编辑:具体回答repository.stream.listen((...) => emit)
与emit.forEach((... )=>repository.stream)
:
它们是等价的。在 Bloc 中,您可以交换两种语法。但在 Cubit 中,emit
是一个函数,而不是 Emitter
,因此您无法访问 emit.forEach
。
关于 block 和肘的区别:
它们非常等效,Bloc 和 Cubit 之间的主要区别在于事件系统。
肘
有一个交互 -> 您调用 Cubit 的函数 -> 它更新状态。基本上,您是在告诉您的肘节“嘿,这刚刚发生,请这样做”。
好处:
- 更少的样板文件,因为您不必创建与交互一样多的事件
- 小部件和逻辑之间的直接链接;事件有时看起来像意大利面条代码
Bloc
有一个交互 -> 您向 Bloc 发送一个事件 -> 它更新状态。基本上你是在告诉你的 Bloc “嘿,这件事刚刚发生了,这取决于你该怎么做”。
好处:
- 逻辑更像是一个黑匣子,因为小部件和处理之间没有直接依赖关系
- 您可以将 Rx Observables 应用到事件流;例如,如果您想在用户交互后延迟或限制某些处理
关于flutter - `Bloc`和 `Cubit`是否完全等价?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75613859/