async/await是Future/then的语法糖,官方为了解决Future/then的死亡嵌套,出的语法糖。下面写一下他们之间的转换关系
下面是一个async/await的语法糖写法
test() async {print('test');await Future(() async {print('f1');await Future(() => print('f2'));print('f1-2');});print('test-2');}
下面是转化为Future/then原始写法
test2() {print('test');return Future(() {print('f1');return Future(() => print('f2')).then((value) => print('f1-2'));}).then((value) => print('test-2'));}
下面说一下具体的转化过程
首先说明几个点:
- async声明的函数为异步函数,返回值是一个Future对象
- await关键字表示异步等待,await下方的代码在异步任务结束后才会执行
下面我们先分析一下async/await的执行顺序
1,test方法被调用后,首先打印test,因为他是同步方法。
2,然后遇到第一个await关键字,这时候await关键字将整个方法体分成2部分,await之后的代码块2需要等待代码块1执行完后才可以执行。所以会打印f1。
3,同理,f2和f1-2会以此打印。
4,最后打印test-2
5,所以整个的打印顺序为
然后我们在看一下async/await语法糖是如何转化为Future/then的写法的
- 去掉async关键字;
- await关键字声明的Future,将作为test的返回值;
- await关键字下方的代码块,将作为Future的then函数中的函数体。


2,同理,继续转化内部的async/await语法糖
- 去掉async关键字;
- await关键字声明的Future,将作为test的返回值;
- await关键字下方的代码块,将作为Future的then函数中的函数体。
最后看一下转换后的代码执行顺序

打印顺序如下
可以看出,转化后的代码和转化前执行顺序是完全一致的。
总结
熟悉async/await语法糖和Future/then的转化可以让我们对于事件循环机制更加清楚,转化步骤只需要3步口诀:
1隐:隐藏async关键字
2返:await关键字声明的Future变为返回值
3替换:await关键字一下的所有代码块都作为Future的then函数体
