DartLibrary 中有很多返回 FutureSteam 对象的函数,他们都是异步函数。

Dart 中,使用 asyncawait 关键字来实现异步编程,它可以让你用同步的方式来写异步代码。

Feature

Future 对象表示在未来的某个时刻的一个 valueerror,所以 Future 可以定义一个 valueerror 的回调。

创建 Future

一个普通的同步方法,如下:

1
String getVersion() => '1.0.0';

将它声明成异步方法,则是这样的:

1
Future<String> getVersion() async => '1.0.0';

通过使用 async 关键字标记一个函数,这个函数就变成了异步函数,它的返回值就变成了 Future<T>。在函数内你可以直接返回 TDart 会自动转换成 Future<T>

当然你也可以,自己创建一个 Future 对象返回,这时函数的 async 标记就不是必须了:

1
Future<String> getVersion() => Future.sync(() => "1.0.0");
1
Future<String> getVersion() => Future.delayed(Duration(seconds: 1), () => "1.0.0");

处理 Future

1
2
Future<String> version = getVersion();
version.then((version) => {print(version)}, onError: (e) => {print(e)});
1
version.then((version) => {print(version)}).catchError((e) => {print(e)});

await 关键字表示等待一个异步函数的返回值,是阻塞式的。所以必须在这个方法上也标记上 async,这就是所谓的用同步的方式写异步代码。

1
2
3
checkVersion() async {
String version = await getVersion();
}

Stream

  • Stream 表示一个异步的数据序列(数据流)
  • Stream 可以来自用户事件,文件等等
  • 使用 await forlisten() 来操作 Stream
  • Stream 提供了一个处理错误的方式
  • 有两种 Stream 定义订阅和广播

创建 Stream

使用 async* 标记一个函数,yield 返回 Stream 数据流

1
2
3
4
5
Stream<int> countStream(int to) async* {
for (int i = 1; i <= to; i++) {
yield i;
}
}

处理 Stream

使用 awit for 来接收数据流

1
2
3
await for (var value in stream) {
sum += value;
}

使用 try catch 来处理错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Future<int> sumStream(Stream<int> stream) async {
var sum = 0;
try {
await for (var value in stream) {
sum += value;
}
} catch (e) {
return -1;
}
return sum;
}

Stream<int> countStream(int to) async* {
for (int i = 1; i <= to; i++) {
if (i == 4) {
throw new Exception('Intentional exception');
} else {
yield i;
}
}
}

Steam 还有很多其他操作符,这部分和 RxJavaJava 8Stream API 很像,包括 RxDart 的实现也是用了大量的 Stream,详情后续在介绍

相关文档