概念介绍
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,如果你是一个喜欢思考的人,欢迎加入群一起交流学习,拒绝伸手党。
欢迎加入Flutter开发群457664582,点击加入,大家一起学习讨论