本节目标
- 同步、异步
syncasync - 关键字
awaityield - 加上
*的区别
视频
代码
正文
在 BLOC 中常见 yield yield* Stream
计算器 Bloc 代码
我们可以发现在 bloc 模块中,非常多 yield* yield async* ,如何正确使用还是很重要的,所以这篇文章把同步、异步的对应的操作符都整理出来。
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 可序列化对象
- 代码
main() {
getList(10).forEach(print);
}
Iterable<int> getList(int count) sync* {
for (int i = 0; i < count; i++) {
yield i;
}
}
- 输出
0
1
2
3
4
5
6
7
8
9
Exited
- 我如果把
sync的*去掉,编辑器会提示这是固定格式。
同步 sync* + yield*
带上 * 因为 yield 返回对象是 Iterable
- 代码
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;
}
}
- 输出
0
1
2
3
4
5
6
7
8
9
Exited
- 我把
yield的*去掉后,提示返回Iterable<T>必须带上*
异步 async + await
Future + async + await 经典配合
常见场景,等待异步完成,比如拉取数据、 IO 操作
- 代码
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));
}
- 输出
start..........
0
Exited
这里就直接返回了, 没有后续的任何操作。
异步 async* + yield
带上 * 后,yield 返回 Stream 对象
接收方用 listen(...)
- 代码
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;
}
}
- 输出
0
1
2
3
4
5
6
7
8
9
Exited
- yield 必须和
async*或sync*配套使用
异步 async* + yield*
yield* 后返回的是另一个 Stream 对象
- 代码
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;
}
}
- 输出
0
1
2
3
4
5
6
7
8
9
Exited
- 返回
Stream<T>类型必须是用yield*的方式
© 猫哥