zil*_*nas 2 dart flutter bloc flutter-bloc
我正在尝试在 Flutter Bloc 中创建一个计时器,以便在调用 DataFetchRequested 事件后每 30 秒获取一次数据。
\n\n\nclass DataBloc extends Bloc<BlocEvent, BlocState> {\n final Api _api;\n Timer _timer;\n\n DataBloc(this._api);\n\n @override\n BlocState get initialState => StateInitial();\n\n @override\n Stream<BlocState> mapEventToState(BlocEvent event) async* {\n if (event is DataFetchRequested) {\n _resetTimer((timer) => _fetchData());\n yield* _fetchData();\n }\n }\n\n Stream<BlocState> _fetchData() async* {\n yield StateLoading();\n\n try {\n final result = await _api.fetch();\n yield StateSuccess(result);\n } catch (e) {\n _timer.cancel();\n yield StateFailure(e.toString());\n }\n }\n\n _resetTimer(void Function(Timer) onCallback) {\n _timer?.cancel();\n _timer = Timer.periodic(Duration(seconds: 1), onCallback);\n }\n\n @override\n Future<void> close() {\n _timer?.cancel();\n return super.close();\n }\n}\n\n\nRun Code Online (Sandbox Code Playgroud)\n\n然而,以这种方式调用时,计时器不会执行任何操作。
\n\n尝试改变
\n\n_resetTimer((timer) => fetchFn);\nRun Code Online (Sandbox Code Playgroud)\n\n到
\n\nyield* _resetTimer((timer) async* {\n yield* fetchFn;\n});\nRun Code Online (Sandbox Code Playgroud)\n\n这导致了错误:
\n\nTried calling: listen(Closure: (Object) => void from Function \'_add@4048458\':., cancelOnError: false, onDone: Closure: () => void from Function \'_close@4048458\':., onError: Closure: (Object, StackTrace) => void from Function \'_addError@4048458\':.) occurred in bloc Instance of \'DataBloc\'.\n#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)\n#1 new _AddStreamState (dart:async/stream_controller.dart:900:34)\n#2 new _StreamControllerAddStreamState (dart:async/stream_controller.dart:952:9)\n#3 _StreamController.addStream (dart:async/stream_controller.dart:571:13)\n#4 _AsyncStarStreamController.addStream (dart:async-patch/async_patch.dart:206:37)\n#5 DataBloc.mapEventToState \npackage:app/\xe2\x80\xa6/data/DataBloc.dart:33\n<asynchronous suspension>\n#6 Bloc._bindEventsToStates.<anonymous closure> <\xe2\x80\xa6>\nRun Code Online (Sandbox Code Playgroud)\n\n是否可以使用 Bloc 中的 Timer 每 30 秒获取一次数据?
\n\n尝试使用 Stream.periodic,但也失败了。
\n\n我能够通过在演示文稿小部件中使用计时器并每 30 秒调用一次事件来实现我想要的目标,但我想将此逻辑从演示文稿小部件移动到 DataBloc - 这可能吗?
\n我认为这应该有效;
class DataBloc extends Bloc<BlocEvent, BlocState> {
final Api _api;
StreamSubscription _periodicSubscription;
DataBloc(this._api);
@override
BlocState get initialState => StateInitial();
@override
Stream<BlocState> mapEventToState(BlocEvent event) async* {
if (event is DataFetchRequested) {
yield StateLoading();
if(_periodicSubscription == null) {
_periodicSubscription ??=
Stream.periodic(const Duration(seconds: 30), (x) => x).listen(
(_) => add(const FetchEvent()),
onError: (error) =>
print("Do something with $error")
);
} else {
_periodicSubscription.resume();
}
}
if(event is FetchEvent){
yield StateLoading();
try {
final result = await _api.fetch();
yield StateSuccess(result);
} catch (e) {
_periodicSubscription.pause();
yield StateFailure(e.toString());
}
}
}
@override
Future<void> close() async {
await _periodicSubscription?.cancel();
_periodicSubscription = null;
return super.close();
}
}
Run Code Online (Sandbox Code Playgroud)
FetchEvent是您必须创建的新事件类。
| 归档时间: |
|
| 查看次数: |
6090 次 |
| 最近记录: |