一,概述
在Dart1.9中加入了async和await关键字,有了这两个关键字,我们可以更简洁的编写异步代码,而不需要调用Future相关的API。他们允许你像写同步代码一样写异步代码和不需要使用Future接口。相当于都Future相关API接口的另一种封装,提供了一种更加简便的操作Future相关API的方法
将 async 关键字作为方法声明的后缀时,具有如下意义
- 被修饰的方法会将一个 Future 对象作为返回值
- 该方法会同步执行其中的方法的代码直到第一个 await 关键字,然后它暂停该方法其他部分的执行;
- 一旦由 await 关键字引用的 Future 任务执行完成,await的下一行代码将立即执行。
二,Async/await 示例解析
- 示例一:
使用Async/await
也是可以实现异步操作,下面直接上例子:
main() { create(); }
void create(){ String data = getData(); print(data); print("I love Future"); }
getData() async{ return await "I love Android"; }
运行上面代码,报错了:
type 'Future<dynamic>' is not a subtype of type 'String'
报的是类型不匹配?为什么呢?经过一番搜查,发现
getData
是一个异步操作函数,它的返回值是一个await
延迟执行的结果。在Dart
中,有await
标记的运算,其结果值是一个Future
对象,Future
并不是String类型,就报错了。那么怎么才正确获得异步的结果呢?Dart规定async标记的函数,只能由await来调用,下面改成这样:main() { create(); } void create() async{ String data = await getData(); print(data); print("I love Future"); }
getData() async{ return await "I love Android"; }下面直接去掉
async
函数包装,直接在getData
方法里对data
进行赋值:String data; main() { create(); }
void create(){ getData(); print("I love Future"); }
getData() async{ data = await "I love Android"; print(data); }上面输出结果是:
I love Future I love Android
可以发现,先输出的是
I love Future
后面再输出I love Android
,可以发现当函数被async
修饰时,会先去执行下面的操作,当下面的操作执行完,然后再执行被async
修饰的方法。async
用来表示函数是异步的,定义的函数会返回一个Future
对象,await
后面是一个Future
,表示等待该异步任务完成,异步完成后才会往下走。要注意以下几点: - await关键字必须在async函数内部使用,也就是加await不加async会报错。
- 调用async函数必须使用await关键字,如果加async不加await会顺序执行代码。
PS: await 关键字真的很形象,等一等的意思,就是说,既然你运行的时候都要等一等,那我调用的时候也要等等吧。
- 示例二:
main() { _startMethod(); _method_C(); } _startMethod() async{ _method_A(); await _method_B(); print("start结束"); }
_method_A(){ print("A开始执行这个方法~"); } _method_B() async { print("B开始执行这个方法~"); await print("后面执行这句话~"); print("继续执行这句哈11111~"); } _method_C(){ print("C开始"); }
结果如下:
A开始执行这个方法~ B开始执行这个方法~ 后面执行这句话~ C开始 继续执行这句哈11111~ start结束
过程分析:
- 当使用async作为方法名后缀声明时,说明这个方法的返回值是一个Future;
- 当执行到该方法代码用await关键字标注时,会暂停该方法其他部分执行;
- 当await关键字引用的Future执行完成,下一行代码会立即执行。
也就是首先执行_startMethod
这个方法用async声明了,因为方法里调用了_method_A
,所以先输出print("A开始执行这个方法~");,后面执行_method_B()
,这个方法用await关键字声明,所以会暂停print("start结束");的执行,然后继续执行_method_B()
将print("B开始执行这个方法~");输出,下一行遇到await关键字,会暂停其他代码的执行。当await关键字引用的Future执行完成(也就是执行print("后面执行这句话~"),_method_C()
方法会立即执行,然后执行继续执行这句哈11111~,最后执行print("start结束");