瞭解過Flutter的同窗都知道,不一樣於 Android 原生開發,dart 是單線程實體的語言,因此咱們通常的異步操做,實際上仍是經過單線程經過調度任務優先級來實現的,就是咱們常常用到的 Future,可是Flutter中的事件機制到底是怎樣的?多個Future 和 Microtask 程序的執行順序是怎樣的? 本文將藉助兩個比較複雜的例子來詳細介紹 Flutter 的事件機制,但願能對你們有所幫助。git
首先我得提一嘴 isolate(隔離),isolate是有本身的內存和單線程控制的運行實體,isolate相似於線程。 運行中的 Flutter 程序由一個或多個 isolate 組成。咱們的代碼默認都在 Main isolate中執行。
爲了保持高的響應性,特別耗時的任務通常不要放在Main isolate 中。但 isolate 不是本文的重點,在此就不過多贅述。github
Dart 中事件機制的實現 :Main isolate 中有一個Looper,但存在兩個Queue:Event Queue 和 Microtask Queue 。
由於 isolate 是單線程實體,因此 isolate中的代碼是按順序執行的。
因此 dart 中的代碼執行優先級能夠分爲三個級別:
bash
總結:Dart 中事件的執行順序:Main > MicroTask > EventQueue。
如圖:app
void testSX(){
new Future(() => print('s_1'));
scheduleMicrotask(() => print('s_2'));
print('s_3');
}
複製代碼
輸出結果:異步
I/flutter (32415): s_3
I/flutter (32415): s_2
I/flutter (32415): s_1
複製代碼
前面講到,用 async 和 await 組合,便可向 event queue 中插入 event 實現異步操做,那爲何還會有Future呢?
其實,Future 最主要的功能就是提供了鏈式調用。async
new Future (() => print('拆分任務_1'))
.then((i) => print('拆分任務_2'))
.then((i) => print('拆分任務_3'))
.whenComplete(()=>print('任務完成'));
複製代碼
Future中的 then 並無建立新的Event丟到Event Queue中,而只是一個普通的Function,在一個 Future 全部的 Function 執行完後,下一個 Future 纔會開始執行。oop
理論結束,而後來看一段代碼吧:ui
void testFuture() {
Future f1 = new Future(() => print('f1'));
Future f2 = new Future(() => null);
Future f3 = new Future.delayed(Duration(seconds: 1) ,() => print('f2'));
Future f4 = new Future(() => null);
Future f5 = new Future(() => null);
f5.then((_) => print('f3'));
f4.then((_) {
print('f4');
new Future(() => print('f5'));
f2.then((_) {
print('f6');
});
});
f2.then((m) {
print('f7');
});
print('f8');
}
複製代碼
各位同窗能夠試着寫一下結果,而後對比下輸出結果。spa
輸出結果:線程
com.example.flutter_dart_app I/flutter: f8
com.example.flutter_dart_app I/flutter: f1
com.example.flutter_dart_app I/flutter: f7
com.example.flutter_dart_app I/flutter: f4
com.example.flutter_dart_app I/flutter: f6
com.example.flutter_dart_app I/flutter: f3
com.example.flutter_dart_app I/flutter: f5
com.example.flutter_dart_app I/flutter: f2
複製代碼
是否是跟本身的結果截然不同,別急,看我來慢慢分析: 分析:
是否是有點理解不了,沒事,牢記四個規則,本身再算一遍,相信你就瞭然於胸了。重要要在腦海裏有一個 EventQueue 的隊列模型,牢記先進先出。
而後來試一試下一題:
void testScheduleMicrotatsk() {
scheduleMicrotask(() => print('Mission_1'));
//註釋1
new Future.delayed(new Duration(seconds: 1), () => print('Mission_2'));
//註釋2
new Future(() => print('Mission_3')).then((_) {
print('Mission_4');
scheduleMicrotask(() => print('Mission_5'));
}).then((_) => print('Mission_6'));
//註釋3
new Future(() => print('Mission_7'))
.then((_) => new Future(() => print('Mission_8')))
.then((_) => print('Mission_9'));
//註釋4
new Future(() => print('Mission_10'));
scheduleMicrotask(() => print('Mission_11'));
print('Mission_12');
}
複製代碼
你們能夠先本身試一下,再對照結果~
輸出結果:
I/flutter (19025): Mission_12
I/flutter (19025): Mission_1
I/flutter (19025): Mission_11
I/flutter (19025): Mission_3
I/flutter (19025): Mission_4
I/flutter (19025): Mission_6
I/flutter (19025): Mission_5
I/flutter (19025): Mission_7
I/flutter (19025): Mission_10
I/flutter (19025): Mission_8
I/flutter (19025): Mission_9
Syncing files to device MIX 3...
I/flutter (19025): Mission_2
複製代碼
是否是仍是沒答全對?不要緊,很正常,看我慢慢道來:
分析:
看到這裏,相信各位同窗已經對 Dart 事件機制有一個大概的瞭解,但願能對 各位在學Flutter 的同窗有所幫助,蟹蟹~
我是雷加,若是您喜歡個人文章,請留下你的贊;若有疑問和建議,請在評論區留言
個人 Github, 歡迎關注~