Dart 有一些语言特性来支持 异步编程。 最常见的特性是 async 方法和 await 表达式。
Dart 库中有很多返回 Future 或者 Stream 对象的方法。 这些方法是 异步的: 这些函数在设置完基本的操作 后就返回了, 而无需等待操作执行完成。 例如读取一个文件,在打开文件后就返回了。
有两种方式可以使用 Future 对象中的 数据:
async
和 await
Future API
同样,从 Stream 中获取数据也有两种 方式:
async
和一个 异步 for 循环 (await for
)Stream API
使用 async 和 await 的代码是异步的, 但是看起来有点像同步代码。 例如,下面是一些使用 await 来 等待异步方法返回的示例:
await lookUpVersion()
要使用 await,其方法必须带有 async 关键字:
checkVersion() async {
var version = await lookUpVersion();
if (version == expectedVersion) {
// Do something.
} else {
// Do something else.
}
}
可以使用 try, catch, 和 finally 来处理使用 await 的异常:
try {
server = await HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 4044);
} catch (e) {
// React to inability to bind to the port...
}
一个 async 方法 是函数体被标记为 async 的方法。 虽然异步方法的执行可能需要一定时间,但是 异步方法立刻返回 - 在方法体还没执行之前就返回了。
checkVersion() async {
// ...
}
lookUpVersion() async => /* ... */;
在一个方法上添加 async 关键字,则这个方法返回值为 Future。 例如,下面是一个返回字符串 的同步方法:
String lookUpVersionSync() => '1.0.0';
如果使用 async 关键字,则该方法 返回一个 Future,并且 认为该函数是一个耗时的操作。
Future<String> lookUpVersion() async => '1.0.0';
注意,方法的函数体并不需要使用 Future API。 Dart 会自动在需要的时候创建 Future 对象。
await 表达式具有如下的形式:
await expression
在一个异步方法内可以使用多次 await
表达式。 例如,下面的示例使用了三次 await 表达式 来执行相关的功能:
var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
在 await expression
中, expression
的返回值通常是一个 Future; 如果返回的值不是 Future,则 Dart 会自动把该值放到 Future 中返回。 Future 对象代表返回一个对象的承诺(promise)。 await expression 执行的结果为这个返回的对象。 await expression 会阻塞住,直到需要的对象返回为止。
如果 await 无法正常使用,请确保是在一个 async 方法中。 例如要在 main() 方法中使用 await, 则 main() 方法的函数体必须标记为 async:
main() async {
checkVersion();
print('In main: version is ${await lookUpVersion()}');
}
异步 for 循环具有如下的形式:
await for (variable declaration in expression) {
// Executes each time the stream emits a value.
}
上面 expression 返回的值必须是 Stream 类型的。 执行流程如下:
使用 break 或者 return 语句可以 停止接收 stream 的数据, 这样就跳出了 for 循环并且 从 stream 上取消注册了。
如果异步 for 循环不能正常工作, 确保是在一个 async 方法中使用。 例如,要想在 main() 方法中使用异步 for 循环,则需要把 main() 方法的函数体标记为 async:
main() async {
...
await for (var request in requestServer) {
handleRequest(request);
}
...
}
关于异步编程的更多信息,参考 dart:async。 另外还 可以参考 Dart Language Asynchrony Support: Phase 1 和 Dart Language Asynchrony Support: Phase 2, 以及 Dart 语言规范。
Copyright© 2013-2019