一文完全搞懂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開發

相關文章
相關標籤/搜索