一文完全搞懂Dart的event队列

概念介绍

event队列和microtask是dart包里的代码,这部分知识是作Flutter必懂的知识,至于event队列和microtask是什么本身谷歌,我就不赘述了。而后我发一段代码,在不运行的状况下,请思考输出什么bash

第一次练习

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 BC end from BFuture方法里的内容不输出是由于在这里只是把这个Future加入到event事件队列,而后运行到methodC('main'),同刚才同样,输出C start from mainC end from main,这里的Future方法也是加到了event事件队列,而后执行methodD()方法,输出D,而后同步方法main执行完毕,开始执行event事件队列里的事件,按照刚才加入event事件队列的顺序,先执行methodB(),打印B end,而后打印C running Future from BC end of Future from BC running Future from mainC end of Future from mainasync

添加注释后的代码以下

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');//三、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');//四、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 BC end of Future from BC running Future from mainC end of Future from mainui

添加注释后的代码以下

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的时候会等待执行完毕。spa

还有一个microtask,原理和这个同样,混合使用的时候,在主方法执行完毕之后,会先取microtask队列的事件执行,都执行完之后再从event队列里取事件执行。3d

有问题请留言,欢迎加入QQ群:457664582,若是你是一个喜欢思考的人,欢迎加入群一块儿交流学习,拒绝伸手党。code

欢迎加入Flutter开发群457664582,点击加入,你们一块儿学习讨论cdn

Flutter开发

相关文章
相关标签/搜索