Dart做爲Flutter的開發語言,瞭解Dart的機制是必可少的。本篇文章就介紹一下Dart的異步操做與事件循環機制。java
異步操做咱們都知道在開發過程當中,若是有耗時操做,咱們通常都會使用異步任務解決,以防主線程卡頓。markdown
事件循環是Dart中處理事件的一種機制。Flutter中就是經過事件循環來驅動程序的運行,這點與Android中的Handler有點相似。異步
Dart語言是單線程模型的語言。這也就意味着Dart在同一時刻只能執行一個操做,其餘操做在這個操做以後執行。那麼Dart的其餘操做如何執行呢?在Dart中經過Event Loop來驅動事件的執行。async
上面的圖片描述了Dart的事件循環機制。能夠看到,Dart執行事件的流程是:函數
能夠看到,main()方法的優先級最高,執行結束後,才執行兩個隊列中事件。其中MicroTask隊列的優先級又高於Event隊列的優先級。微服務
MicroTask 隊列適用於很是簡短且須要異步執行的內部動做或者想要在Event執行前作某些操做,由於在MicroTask執行完之後,還須要執行Event隊列中事件。oop
在使用Dart時異步事件應該優先考慮使用Event隊列。ui
Future 是一個異步執行而且在將來的某一個時刻完成(或失敗)的任務。每個Future都會執行一個事件而且將事件加入到Event隊列中去。spa
factory Future(FutureOr<T> computation()) {
_Future<T> result = new _Future<T>();
Timer.run(() {
try {
result._complete(computation());
} catch (e, s) {
_completeWithErrorCallback(result, e, s);
}
});
return result;
}
複製代碼
從上面Future的構造函數代碼能夠看到,經過Timer的run()方法將運算過程發送到事件隊列中去,而後經過_complete()方法獲取了提交給Future的運算結果,最終返回一個Future對象。pwa
void main(){
print('Before the Future');
Future((){
print('Running the Future');
}).then((_){
print('Future is complete');
});
print('After the Future');
Future<String>.microtask(() {
return "microtask";
}).then((String value) {
print(value);
});
}
複製代碼
以上代碼的運行結果是:
Before the Future
After the Future
microtask
Running the Future
Future is complete
複製代碼
能夠看到,這裏先執行的是main()方法中的打印信息,而後打印了microtask,最後才執行了Future。這裏也能夠證實Future是在事件隊列中執行的。
async與await關鍵字配合使用能夠更加優雅的處理dart中的異步。對於有async修飾的函數來講,它會同步執行函數中的代碼,直到遇到第一個await關鍵字,而後將await修飾的代碼提交到事件隊列中處理,在await修飾的代碼執行完畢後會當即執行剩下的代碼,而剩下的代碼將在微任務隊列中執行。
void methodAsync() async {
sleep(Duration(seconds: 1));
Future<String>(() {
return "future 1";
}).then((String value) {
print(value);
});
print("async start");
await microTaskAndEvent(); //輸出一個微任務打印 microtask 以及一個事件隊列任務打印 futrue
print("async end");
}
void main() {
methodAsync();
print("Hello World");
}
複製代碼
以上代碼的輸出結果是:
async start
Hello World
microtask
async end
future 1
future
複製代碼
從打印結果能夠看出,
Isolate從名稱上理解是獨立的意思。在dart中,Isolate有着本身的內存而且不存在經過共享內存的方式實現Isolate之間的通訊,同時Isolate是單線程的計算過程。
Isolate的特色與使用:
接下來經過一個例子展現Isolate的通訊以及建立過程。
main() async {
var receivePort = new ReceivePort();
/** * 初始化另一個Isolate, * 將main isolate的send port發送到child isolate中, * 用於向main isolate發送信息 */
await Isolate.spawn(echo, receivePort.sendPort);
// child isolate的第一個信息做爲child isolate的send port,因爲向child isolate發送信息
var sendPort = await receivePort.first;
var msg = await sendReceive(sendPort, "hello");
print('received $msg');
msg = await sendReceive(sendPort, "close");
print('received $msg');
}
// child isolate的入口
echo(SendPort sendPort) async {
// 打開一個接收端口
var port = new ReceivePort();
//監聽接收的信息
port.listen((dynamic msg) {
print("child receive $msg");
var data = msg[0];
SendPort replyTo = msg[1];
replyTo.send(data);
if (data == "close") port.close(); //關閉接收端口
});
// 向其餘的isolate通知child isolate的發送端口.
sendPort.send(port.sendPort);
}
//發送信息
Future sendReceive(SendPort port, msg) {
ReceivePort response = new ReceivePort();
port.send([msg, response.sendPort]);
return response.first;
}
複製代碼
以上就是關於Dart的異步以及事件循環原理。理解這些內容是必要的,由於在不少的開發場景都會用到異步,同時須要很好的理解Dart的事件處理機制。