在Flutter開發中,Dart執行任務原則如同Android中的Handler壹樣,也是依靠事件驅動的。如圖所示,當main方法執行後就生成了壹個eventloop時間循環,通過eventloop不停的從時間隊列中獲取事件消息來完成程序中所有任務的執行。事件消息包括微任務隊列microtask和事件隊列eventqueue,其中microtask的優先級高於eventqueue,也就是說eventloop每執行完畢壹次事件後,都會再次查詢事件隊列中是否存在microtask任務,如果存在則優先執行,直到隊列中不再存在microtask任務才會執行eventqueue任務,所以可以根據此特性在程序中對壹個優先級高的任務做事件插隊。
下面用代碼驗證壹下。上篇文章介紹了isolate中使用receivePort進行消息通信,這裏receivePort的listen監聽回調中的代碼屬於eventqueue任務,通過Future.microtask方法可以創建壹個微任務隊列。如控制臺所示,當eventloop中存在microtask時,它壹定會優先執行,而並不是像代碼所寫的順序那樣按序執行。
voidmain(){ReceivePortreceivePort=ReceivePort();receivePort.listen((message){print(message);});Future.microtask((){print("這是微任務隊列");});receivePort.sendPort.send("這是給eventqueue隊列的消息");Future.microtask((){print("這是微任務隊列2");});receivePort.sendPort.send("這是給eventqueue隊列的消息2");}在上面的基礎上,如果在某個微任務增加耗時操作,則後面的任務都會等待微任務結束後再執行,在如下代碼中,在第壹個微任務中sleep兩秒後,後面的任務才得以執行。所以在使用時,即使要使用microtask插入壹個優先級高的任務,也需要註意不要執行耗時較高的操作,這也正是單線程模型的特性。
總結Dart事件隊列循環包括兩種隊列:事件隊列(eventqueue),包含所有的外來事件:I/O、mouseevents、drawingevents、timers、isolate之間的信息傳遞。
微任務隊列(microtaskqueue),表示壹個短時間內就會完成的異步任務。它的優先級最高,高於eventqueue,只要隊列中還有任務,就可以壹直霸占著事件循環。microtaskqueue添加的任務主要是由Dart內部產生。
事件循環原則優先執行任務隊列中的微任務。
即使當前隊列中eventqueue任務數量再多,執行完壹個任務後也會再次判斷隊列裏是否包含微任務隊列,如果有則執行,若沒有則查詢是否有eventqueue任務。