Handle concurrent event Flutter
Chào mọi người,
Có ai từng làm việc với Bloc library và phải handle concurrent event chưa ạ?
Mỗi event cần xử lý call API, em có dùng async để cancel future call trong trường hợp user bấm tạo event nhiều rồi. Nhưng vẫn gặp phải trường hợp future cancel ko nhanh bằng event mới được add thêm vào => nhiều event 1 lúc handle dẫn đến sai logic.
Vi dụ: user upload ảnh 1 qua API, nhưng user cancel ảnh nhanh và chọn ảnh 2, thì sẽ có trường hợp e ko cancel được event của ảnh 1 dẫn đến sai logic.
Mong mọi người giúp đỡ ạ.
Remain: 5
3 Answers
monkey
Beginner
monkey
Beginner
Em có thể cung cấp source code của em để anh tái hiện lại cho nhanh không em? Sử dụng thẻ pre để paste code em nhé.
-
0
monkey
Beginner
monkey
Beginner
Thực tế async này nó sẽ sử dụng các luồng ở background để lập lịch, sau đó đến thời điểm nó sẽ đưa các event vào main queue từ đó mà các event này được chạy trên luồng chính. Chính vì điều này mà code của em bị chạy lung tung, vì việc xử lý ở background có thời gian hoàn thành khác nhau, dẫn đến các sự kiện xảy ra trên luồng chính sẽ không theo tuần tự.
Em thử code này xem sao nhé:
<span>import</span> <span>'package</span>:bloc/bloc.dart'; <span>import</span> <span>'package</span>:bloc_concurrency/bloc_concurrency.dart'; <span>abstract</span> <span><span>class</span> <span>BaseEvent</span> </span>{} <span><span>class</span> <span>PickImageEvent</span> <span>extends</span> <span>BaseEvent</span> </span>{} <span><span>class</span> <span>IdentifyImageEvent</span> <span>extends</span> <span>BaseEvent</span> </span>{} <span><span>class</span> <span>ShowResultEvent</span> <span>extends</span> <span>BaseEvent</span> </span>{} <span><span>class</span> <span>BaseState</span> </span>{ } <span><span>class</span> <span>BlockProxy</span> <span>extends</span> <span>Bloc<BaseEvent</span>, <span>BaseState></span> </span>{ <span>var</span> _counter = <span>0</span>; <span>BlockProxy</span>(<span>var</span> testCounter) : <span>super</span>(<span>BaseState</span>()) { _counter = testCounter; on<<span>PickImageEvent</span>>(_onPickImageEvent, transformer: restartable()); on<<span>IdentifyImageEvent</span>>(_onIdentifyImageEvent, transformer: restartable()); on<<span>ShowResultEvent</span>>(_onShowResultEvent, transformer: restartable()); } <span>Future</span> _onPickImageEvent(event, emit) async { print(<span>'Start</span> picking image | <span>Counter</span> $_counter'); await <span>Future</span>.delayed(const <span>Duration</span>(seconds: <span>5</span>)); <span>if</span> (!isClosed) { print(<span>'Have</span> picked an image | <span>Counter</span> $_counter'); add(<span>IdentifyImageEvent</span>()); } } <span>Future</span> _onIdentifyImageEvent(event, emit) async { print('> <span>Start</span> identifying that image | <span>Counter</span> $_counter'); await <span>Future</span>.delayed(const <span>Duration</span>(seconds: <span>3</span>)); <span>if</span> (!isClosed) { print('> <span>Finished</span> identifying that image | <span>Counter</span> $_counter'); add(<span>ShowResultEvent</span>()); } } <span>Future</span> _onShowResultEvent(event, emit) async { print('>> <span>Start</span> showing result | <span>Counter</span> $_counter'); await <span>Future</span>.delayed(const <span>Duration</span>(seconds: <span>2</span>)); <span>if</span> (!isClosed) { print('>> <span>Stopped</span> showing result | <span>Counter</span> $_counter'); } } } <span><span>class</span> <span>TestBloc</span> </span>{ <span>List</span><<span>BlockProxy</span>> blocList = []; <span>var</span> testCounter = <span>0</span>; void add(<span>PickImageEvent</span> event) async { <span>for</span> (<span>BlockProxy</span> element in blocList) { <span>if</span> (!element.isClosed) { element.close(); } } <span>var</span> bloc = <span>BlockProxy</span>(++testCounter); blocList.add(bloc); bloc.stream.listen(<span>null</span>); bloc.add(event); } } <span>/// Expect result:</span> <span>/// Start picking image | Counter 1</span> <span>/// Start picking image | Counter 2</span> <span>/// Start picking image | Counter 3</span> <span>///</span> <span>/// Have picked an image | Counter 3</span> <span>///</span> <span>/// > Start identifying that image | Counter 3</span> <span>/// > Finished identifying that image | Counter 3</span> <span>///</span> <span>/// >> Start showing result | Counter 3</span> <span>/// >> Stopped showing result | Counter 3</span> void main() { <span>final</span> bloc = <span>TestBloc</span>(); bloc.add(<span>PickImageEvent</span>()); bloc.add(<span>PickImageEvent</span>()); bloc.add(<span>PickImageEvent</span>()); }
-
1
uzumaki258
Beginner
uzumaki258
Beginner
E sẽ dùng cách này, + với giảm event nội bộ. Cảm ơn a đã dành thời gian ạ.
-
0