概念介绍
event队列和microtask是dart包里的代码,这部分知识是做Flutter必懂的知识,至于event队列和microtask是什么自己谷歌,我就不赘述了。然后我发一段代码,在不运行的情况下,请思考输出什么
第一次练习
void main() {
methodA();
methodB();
methodC('main');
methodD();
}
methodA(){
print('A');
}
methodB() async {
print('B start');
await methodC('B');
print('B end');
}
methodC(String from) async {
print('C start from $from');
Future((){
print('C running Future from $from');
}).then((_){
print('C end of Future from $from');
});
print('C end from $from');
}
methodD(){
print('D');
}
复制代码
我们可以分析一下,main是同步方法,所以在main方法里调用的方法如果是async的,会执行到await然后返回future,先看methodA();
这个不用多说直接输出A
。然后看methodB();
,因为main是同步方法所以在await之前的直接运行,所以输出B start
,然后运行到await methodC('B');
,会把methodB
加入到event事件队列
,然后进入methodC
方法直到运行到await
方法之前,所以输出C start from B
,C end from B
,Future
方法里的内容不输出是因为在这里只是把这个Future加入到event事件队列,然后运行到methodC('main')
,同刚才一样,输出C start from main
,C end from main
,这里的Future
方法也是加到了event事件队列,然后执行methodD()
方法,输出D
,然后同步方法main执行完毕,开始执行event事件队列里的事件,按照刚才加入event事件队列的顺序,先执行methodB()
,打印B end
,然后打印C running Future from B
,C end of Future from B
,C running Future from main
,C end of Future from main
。
添加注释后的代码如下
void main() {
methodA();
methodB();
methodC('main');
methodD();
}
methodA(){
print('A');//1
}
methodB() async {
print('B start');//2
await methodC('B');//2之后加入到了event队列
print('B end');//8
}
methodC(String from) async {
print('C start from $from');//3、5
Future((){//3之后加到了event队列,from=B、5之后加到了event队列,from=main
print('C running Future from $from');
}).then((_){
print('C end of Future from $from');
});
print('C end from $from');//4、6
}
methodD(){
print('D');//7
}
复制代码
打印结果如下所示:
A
B start
C start from B
C end from B
C start from main
C end from main
D
B end
C running Future from B
C end of Future from B
C running Future from main
C end of Future from main
复制代码
第二次练习
然后我们换一种方式,代码如下
void main() async {
methodA();
await methodB();
await methodC('main');
methodD();
}
methodA(){
print('A');
}
methodB() async {
print('B start');
await methodC('B');
print('B end');
}
methodC(String from) async {
print('C start from $from');
Future((){
print('C running Future from $from');
}).then((_){
print('C end of Future from $from');
});
print('C end from $from');
}
methodD(){
print('D');
}
复制代码
开始我们的分析,这次的main方法改成了async的,首先输出A
,然后执行到await methodB()
,进入methodB()
方法,输出B start
,然后执行await methodC('B')
,然后输出C start from B
,然后Future
加入事件队列,然后输出C end from B
,然后这次和上次开始有区别了,因为这次的main方法是async的方法,所以在await methodB()
这里会等待methodB()
方法执行完毕,所以下一步输出B end
,然后执行methodC('main')
,输出C start from main
,然后Future
加入事件队列,然后输出C end from main
,然后执行methodD()
输出D
,然后开始从event队列取事件,按照刚才加入event队列的顺序,一次输出C running Future from B
,C end of Future from B
,C running Future from main
,C end of Future from main
添加注释后的代码如下
void main() async {
methodA();
await methodB();
await methodC('main');
methodD();
}
methodA(){
print('A');//1
}
methodB() async {
print('B start');//2
await methodC('B');//因为main方法是async的,所以这里没有加入到event队列而是继续执行
print('B end');//5
}
methodC(String from) async {
print('C start from $from');//3 6
Future((){//3之后加入到event队列、6之后加入到event队列
print('C running Future from $from');
}).then((_){
print('C end of Future from $from');
});
print('C end from $from');//4 7
}
methodD(){
print('D');//8
}
复制代码
打印结果如下所示
A
B start
C start from B
C end from B
B end
C start from main
C end from main
D
C running Future from B
C end of Future from B
C running Future from main
C end of Future from main
复制代码
总结
如果async的方法被同步方法调用,代码会执行到第一个await之前,然后把当前future加入到event队列;如果async的方法被async的方法调用,那么在执行到await的时候会等待执行完毕。
还有一个microtask,原理和这个一样,混合使用的时候,在主方法执行完毕以后,会先取microtask队列的事件执行,都执行完以后再从event队列里取事件执行。
有问题请留言,欢迎加入QQ群:457664582,如果你是一个喜欢思考的人,欢迎加入群一起交流学习,拒绝伸手党。