前言
Dart库充满了返回Future或Stream对象的函数。 这些函数都是异步的:它们在设置可能耗时的操作(例如I/O)之后返回,而无需等待该操作完成。
async和await关键字支持异步编程,使你可以编写看起来类似于同步代码的异步代码。
处理Futures
当你需要一个已经完成的 Future 结果,可以有两个方式:
- 用
async和await - 用 Future API, 在库描述中可以找到
使用async和await的代码是异步的,但是看起来很像同步代码。 例如,下面是一些使用await等待异步函数结果的代码:
await lookUpVersion();
要使用await,代码必须位于async函数中,该函数被标记为async:
Future checkVersion() async {
var version = await lookUpVersion();
// 用version干些事情
}
注意:尽管异步功能可能会执行耗时的操作,但它不会等待这些操作。 相反,异步函数仅在遇到第一个await表达式(详情)之前执行。 然后,它返回Future对象,仅在await表达式完成后才恢复执行。
使用try,catch,finally去处理错误,并且使用await清理代码
try {
version = await lookUpVersion();
} catch (e) {
// 应对 lookUpVersion()失败的情况
}
你可以在async函数中多次使用await。 例如,以下代码等待三遍函数结果:
var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
在await表达式中,表达式的值通常是Future; 如果不是,则该值将自动包装在Future中。 此Future对象指示返回一个对象的承诺。 await表达式的值是返回的对象。 await表达式使执行暂停,直到该对象可用为止。
**如果在使用await时收到编译时错误,请确保await在async函数中。**例如,要在应用程序的main()函数中使用await,必须将main()的正文标记为async:
Future main() async {
checkVersion();
print('In main: version is ${await lookUpVersion()}');
}
定义异步函数
async函数是一个主体带有async修饰符的函数。
向函数添加async关键字使其返回Future。 例如,考虑以下同步函数,该函数返回一个String:
String lookUpVersion() => '1.0.0';
如果将其更改为async函数(例如,由于将来的实现会很耗时),则返回的值将为Future:
Future<String> lookUpVersion() async => '1.0.0';
请注意,该函数的主体不需要使用Future API。 Dart会在必要时创建Future对象。 如果你的函数没有返回有用的值,请使其返回类型为Future<void>。
有关使用futures,async和await的交互式介绍,请参见异步编程代码实验室。
处理流
当你需要从流中获取值,你有两种方式:
- 用
async和一个异步的for循环(await for) - 用Stream API, 在库描述中可以找到
注意:在使用
await之前,请确保它使代码更清晰,并且你确确实实要等待所有流的结果。 例如,你通常不应将await用于UI事件侦听器,因为UI框架发送无休止的事件流。
一个异步循环有以下格式:
await for (varOrType identifier in expression) {
// 每次执行steam(流)都会发出一个值。
}
表达式的值必须具有Stream类型。 执行过程如下:
- 会等到流发出一个值为止
- 执行for循环体,并将变量设置为该发射值。
- 重复1和2,直到关闭流。
要停止监听流,可以使用break或return语句,该语句会脱离for循环并取消订阅流。
如果在实现异步for循环时遇到编译时错误,请确保await for位于async函数中。 例如,要在应用程序的main()函数中使用异步for循环,必须将main()的正文标记为async:
Future main() async {
// ...
await for (var request in requestServer) {
handleRequest(request);
}
// ...
}
通常,有关异步编程的更多信息,请参见库介绍的dart:async部分。