头图

本节目标

  • 同步、异步 sync async
  • 关键字 await yield
  • 加上 * 的区别

视频

https://www.bilibili.com/vide...

代码

https://github.com/ducafecat/...

正文

在 BLOC 中常见 yield yield* Stream<T>

计算器 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<T> 可序列化对象

  • 代码
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<T>

  • 代码
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<T> 对象

接收方用 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<T> 对象

  • 代码
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* 的方式


© 猫哥

https://ducafecat.tech

https://ducafecat.gitee.io


独立开发者_猫哥
666 声望126 粉丝