本节目标
- 同步、异步
sync
async
- 关键字
await
yield
- 加上
*
的区别
视频
https://www.bilibili.com/video/BV1JZ4y1w7hX/
代码
https://github.com/ducafecat/flutter-bloc-learn/tree/master/sync-async
正文
在 BLOC 中常见 yield yield* Stream
计算器 Bloc 代码
我们可以发现在 bloc 模块中,非常多 yield*
yield
async*
,如何正确使用还是很重要的,所以这篇文章把同步、异步的对应的操作符都整理出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class CounterBloc extends Bloc<CounterEvent, CounterState> { CounterBloc() : super(CounterInitial(0));
int counterNum = 0;
@override Stream<CounterState> mapEventToState( CounterEvent event, ) async* { if (event is CounterIncrementEvent) { yield* _mapIncrementEventToState(event); } else if (event is CounterSubductionEvent) { yield* _mapSubductionEventToState(event); } }
Stream<CounterState> _mapIncrementEventToState( CounterIncrementEvent event) async* { this.counterNum += 1; yield CounterChange(this.counterNum); }
Stream<CounterState> _mapSubductionEventToState( CounterSubductionEvent event) async* { this.counterNum -= 1; yield CounterChange(this.counterNum); } }
|
同步 sync* + yield
同步 sync 后返回 Iterable 可序列化对象
1 2 3 4 5 6 7 8 9
| main() { getList(10).forEach(print); }
Iterable<int> getList(int count) sync* { for (int i = 0; i < count; i++) { yield i; } }
|
1 2 3 4 5 6 7 8 9 10 11
| 0 1 2 3 4 5 6 7 8 9 Exited
|
- 我如果把
sync
的 *
去掉,编辑器会提示这是固定格式。
同步 sync + yield
带上 * 因为 yield 返回对象是 Iterable
1 2 3 4 5 6 7 8 9 10 11 12 13
| main() { getList(10).forEach(print); }
Iterable<int> getList(int count) sync* { yield* generate(count); }
Iterable<int> generate(int count) sync* { for (int i = 0; i < count; i++) { yield i; } }
|
1 2 3 4 5 6 7 8 9 10 11
| 0 1 2 3 4 5 6 7 8 9 Exited
|
- 我把
yield
的 *
去掉后,提示返回 Iterable<T>
必须带上 *
异步 async + await
Future + async + await 经典配合
常见场景,等待异步完成,比如拉取数据、 IO 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| main() { print("start.........."); getList(10).then(print); }
Future<int> getList(int count) async { await sleep(); for (int i = 0; i < count; i++) { return i; } return 99; }
Future sleep() async { return Future.delayed(Duration(seconds: 3)); }
|
1 2 3
| start.......... 0 Exited
|
这里就直接返回了, 没有后续的任何操作。
异步 async* + yield
带上 *
后,yield 返回 Stream 对象
接收方用 listen(…)
1 2 3 4 5 6 7 8 9 10
| main() { getList(10).listen(print); }
Stream<int> getList(int count) async* { for (int i = 0; i < count; i++) { await Future.delayed(Duration(seconds: 1)); yield i; } }
|
1 2 3 4 5 6 7 8 9 10 11
| 0 1 2 3 4 5 6 7 8 9 Exited
|
- yield 必须和
async*
或 sync*
配套使用
异步 async + yield
yield* 后返回的是另一个 Stream 对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| main() { getList(10).listen(print); }
Stream<int> getList(int count) async* { yield* generate(count); }
Stream<int> generate(int count) async* { for (int i = 0; i < count; i++) { await Future.delayed(Duration(seconds: 1)); yield i; } }
|
1 2 3 4 5 6 7 8 9 10 11
| 0 1 2 3 4 5 6 7 8 9 Exited
|
- 返回
Stream<T>
类型必须是用 yield*
的方式
© 猫哥
https://ducafecat.tech
https://ducafecat.gitee.io
邮箱 ducafecat@gmail.com / 微信 ducafecat / 留言板 disqus