概念介绍
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}复制代码
打印结果如下所示:
AB startC start from BC end from BC start from mainC end from mainDB endC running Future from BC end of Future from BC running Future from mainC 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}复制代码
打印结果如下所示
AB startC start from BC end from BB endC start from mainC end from mainDC running Future from BC end of Future from BC running Future from mainC end of Future from main复制代码
总结
如果async的方法被同步方法调用,代码会执行到第一个await之前,然后把当前future加入到event队列;如果async的方法被async的方法调用,那么在执行到await的时候会等待执行完毕。
还有一个microtask,原理和这个一样,混合使用的时候,在主方法执行完毕以后,会先取microtask队列的事件执行,都执行完以后再从event队列里取事件执行。
有问题请留言,欢迎加入QQ群:,如果你是一个喜欢思考的人,欢迎加入群一起交流学习,拒绝伸手党。