异步是所有开发语言中非常重要的一环,在执行耗时操作的时候不会让主线程长时间无响应,这一点在移动端开发中尤其重要
Dart库中包含许多返回Future或Stream对象的函数。
这些函数是异步的:它们在设置可能耗时的操作(例如I / O)后返回,而不等待该操作完成。
async和await关键字支持异步编程,允许您编写看起来类似于同步代码的异步代码。
await关键字在Dart2中才加入其中
使用异步的方法有两个,第一个是使用await 另外一个是使用Future Api
使用async和await的代码是异步的,但它看起来很像同步代码。
例如,这里有一些代码使用await来等待异步函数的结果:
await lookUpVersion();
要使用await关键字,需要在async包裹的代码块方法中使用
Future checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
注意:虽然异步函数可能执行耗时的操作,但它不会等待这些操作。
相反,异步函数只在遇到第一个await表达式(详细信息)时才会执行。
然后它返回一个Future对象,仅在await表达式完成后才恢复执行。
你也可以针对await进行一个try catch 防止出现异常
try {
version = await lookUpVersion();
} catch (e) {
// React to inability to look up the version
}
你也可以多次使用await来执行多次耗时操作
var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
以 async 关键字声明的方法必须返回一个Future的对象,如果你需要返回一个有用的值,请将该对象加入到泛型里面
Future lookUpVersion() async => '1.0.0';
当您需要从Stream获取值时,您有两个选择:使用async和异步for循环(等待)
或者使用Stream API,如库浏览中所述。
注意:在使用await for前,请确保它使代码更清晰,并且您确实希望等待所有流的结果。
例如,您通常不应该使用await for UI事件侦听器,因为UI框架会发送无穷无尽的事件流。
异步for循环具有以下形式:
await for (varOrType identifier in expression) {
// Executes each time the stream emits a value. 这个expression需要是一个事件流列表
}
表达式的值必须具有Stream类型。
执行过程如下:
1.等到流发出一个值。
2.执行for循环的主体,将变量设置为该发出的值。
3.重复1和2,直到关闭流。
要停止侦听流,可以使用break或return语句,该语句会从for循环中断开并从流中取消取消。
当您需要懒加载一个序列的值时,请考虑使用生成器函数。Dart内置支持两种生成器功能:同步和异步
要实现同步生成器函数,请将函数体标记为sync *,并使用yield语句来传递值:
Iterable naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
异步的写法很类似,区别就在于关键字
Stream asynchronousNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
如果您的生成器是递归的,则可以使用yield *来提高其性能:
Iterable naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
如果你想你的类可以像方法一样去调用的话,你需要在类里面增加一个call方法