網(wǎng)站首頁 編程語言 正文
前言
最近,小轟參與了公司 flutter 項目關(guān)于 Dart 2.0 的空安全升級工作。我們升級了所有依賴的三方庫,其中就包括有 Bloc 庫。作為一款使用率頗高的狀態(tài)管理框架, Bloc 在版本迭代中進行了少許結(jié)構(gòu)和細節(jié)的優(yōu)化,下面是小轟對于 Bloc 新版本的使用總結(jié)。
使用方式
小轟使用的 Bloc 版本如下
flutter_bloc: ^7.3.1
通過最簡單的例子來學(xué)習(xí)新知識
- 創(chuàng)建一個包含 加 減 操作的頁面,使用 bloc 來操作 自增 自減 事件。
class _TestBlocPageState extends State<TestBlocPage> {
late TestDartBloc _bloc;
@override
void initState() {
super.initState();
_bloc = TestDartBloc(TestDartState(0));
}
@override
Widget build(BuildContext context) {
return BlocBuilder<TestDartBloc, TestDartState>(
bloc: _bloc,
builder: (context, state) {
return Column(
children: [
//顯示當前的數(shù)字結(jié)果
Text(state.num.toString()),
TextButton(
onPressed: () {
//進行自增操作
_bloc.add(IncreaseEvent());
},
child: Text('add')),
TextButton(
onPressed: () {
//進行自減操作
_bloc.add(ReduceEvent());
},
child: Text('reduce')),
],
);
},
);
}
}
Bloc 中 state 和 event 模型定義如下
part of 'test_dart_bloc.dart';
/// Bloc state
class TestDartState {
int num = 0;
TestDartState(this.num);
}
part of 'test_dart_bloc.dart';
/// Bloc event
@immutable
abstract class TestDartEvent {}
//自增事件
class IncreaseEvent extends TestDartEvent{}
//自減事件
class ReduceEvent extends TestDartEvent{}
創(chuàng)建 Bloc ,重寫 mapEventToState 接收事件流轉(zhuǎn)狀態(tài)流
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
part 'test_dart_event.dart';
part 'test_dart_state.dart';
class TestDartBloc extends Bloc<TestDartEvent, TestDartState> {
TestDartBloc(TestDartState state) : super(state);
@override
Stream<TestDartState> mapEventToState(TestDartEvent event) async* {
if (event is IncreaseEvent) {
await Future.delayed(Duration(seconds: 10));
yield TestDartState(state.num + 1);
} else if (event is ReduceEvent) {
yield TestDartState(state.num - 1);
}
}
}
好了,直接運行如上代碼,我們的demo就能完整的跑起來。但,以上的寫法和低版本的 Bloc 完全一致,在經(jīng)歷高版本迭代后,Bloc 到底做了哪些優(yōu)化呢?
Bloc 新形態(tài)用法
小轟在源碼里看到,重寫 mapEventToState 的使用方式已經(jīng)被棄用了,會在將來的某個版本中徹底刪除該 API
/// **@Deprecated - Use on<Event> instead. Will be removed in v8.0.0**
///
/// Must be implemented when a class extends [Bloc].
/// [mapEventToState] is called whenever an [event] is [add]ed
/// and is responsible for converting that [event] into a new [state].
/// [mapEventToState] can `yield` zero, one, or multiple states for an event.
@Deprecated('Use on<Event> instead. Will be removed in v8.0.0')
Stream<State> mapEventToState(Event event) async* {}
新用法推薦使用 on 來進行事件注冊,我們將上面demo中的 bloc 進行寫法改造:
class TestDartBloc extends Bloc<TestDartEvent, TestDartState> {
TestDartBloc(TestDartState state) : super(state) {
init();
}
void init() {
on<IncreaseEvent>((event, emit) async {
await Future.delayed(Duration(seconds: 10));
emit(TestDartState(state.num + 1));
});
on<ReduceEvent>((event, emit) {
state.num - 1;
emit(state);
});
}
}
替換代碼后運行demo,直接成功。
事件隊列的阻塞屬性?
目前最新版本的 Bloc 同時支持 on 與 mapEventToState 兩種寫法,那么這兩種寫法有實際區(qū)別嗎?
小轟在使用老版本(空安全之前)bloc 時總結(jié)過一篇文章 聊聊 Bloc event 的隊列屬性。
在 bloc 的 mapEventToState 方法中,event 隊列是一個阻塞性隊列,先進先出,只有當上一個事件消費完畢后,才會響應(yīng)隊列中的下一個事件。
如上demo( mapEventToState 方式): 自增事件中模擬耗時了10s,當依次點擊 自增 和 自減 按鈕后,由于事件隊列的阻塞特性,自增事件消費10秒后,自減事件才會被 mapEventToState 響應(yīng)。
那么,這個特性在 bloc 迭代新版本后還存在嗎?在最新版本的bloc中,小轟通過demo測試得出結(jié)論:
- 當使用 mapEventToState 方式進行事件捕獲時,event 隊列 保持 阻塞 特性。
- 而使用 on 方式進行注冊監(jiān)聽時,event 隊列 默認是異步非阻塞的,是互不干擾的。如果把 bloc 當作事件總線來使用,小轟認為 異步非阻塞 這樣的設(shè)計更為合理。
提問:如果想使用 on 的方式進行注冊,還想事件隊列保證順序執(zhí)行即保持阻塞特性,應(yīng)該怎么辦呢? 解答:使用 自定義 transformer,這樣就實現(xiàn)了事件同步隊列。
on<IncreaseEvent>((event, emit) async {
await Future.delayed(Duration(seconds: 10));
emit(TestDartState(state.num + 1));
},
transformer: (events, mapper) => events.asyncExpand(mapper),
);
參考鏈接: pub.dev/packages/bl…
原文鏈接:https://juejin.cn/post/7051822753401274375
相關(guān)推薦
- 2022-12-14 詳解如何利用Redis實現(xiàn)生成唯一ID_Redis
- 2022-05-17 基于Pytorch的神經(jīng)網(wǎng)絡(luò)之Regression的實現(xiàn)_python
- 2022-05-25 Python小游戲?qū)崿F(xiàn)實例之接蘋果_python
- 2022-05-11 Springcloud集成Seata分布式事務(wù)
- 2022-10-13 云服務(wù)器Windows?Server2012配置FTP服務(wù)器詳細圖文教程_FTP服務(wù)器
- 2022-09-08 pytorch中Tensor.to(device)和model.to(device)的區(qū)別及說明_p
- 2022-12-03 C++時間函數(shù)整理詳解_C 語言
- 2023-10-16 element組件autofocus( 自動獲取焦點)失效
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支