isolate機制和異步編程

iso機制和異步編程

author:andy

isolate機制

? Dart是基于單線程模型的語言。但是在開發(fā)當中我們經(jīng)常會進行耗時操作比如網(wǎng)絡(luò)請求,這種耗時操作會堵塞我們的代碼,所以在Dart也有并發(fā)機制,名叫isolate。APP的啟動入口main函數(shù)就是一個類似Android主線程的一個主isolate。和Java的Thread不同的是,Dart中的isolate無法共享內(nèi)存。

android--主線程,子線程

dart--主isolate,子isolate

疑問
1.java通過子線程執(zhí)行耗時操作,那么dart語言沒有子線程,如何執(zhí)行耗時的操作

import 'dart:isolate';

void main() {
  Isolate.spawn(entryPoint, "dahai isolate");
  print(‘主isolate打印的。。?!?;
}

void entryPoint(String msg) {
  print(msg);
}

疑問
2.上面打印的k會打印成什么?

import 'dart:isolate';
int k;
void main() {
  k = 10;
  Isolate.spawn(entryPoint, "dahai isolate");
}

void entryPoint(String msg) {
  print(k);
}

疑問
3.主isolate和子isolate如何實現(xiàn)數(shù)據(jù)交互

void main() {
  //主isolate 接收器
  ReceivePort receivePort = new ReceivePort();

  //把主接收器的發(fā)送器,傳送給子isolate
  Isolate.spawn(entryPoint, receivePort.sendPort);

  //主isolate接收的信息打印
  receivePort.listen((data) {
    print(data);
  });
}

void entryPoint(SendPort sendPort) {
  sendPort.send('我是來自于子isolate線程');
}

[圖片上傳失敗...(image-b747c2-1600608831069)]

isolate機制跟Android 的handler機制十分相似,都是使用隊列循環(huán)讀取,那么有啥差別呢?

void main() {
  ReceivePort receivePort = ReceivePort();
  receivePort.sendPort.send('任務(wù)隊列1');
  receivePort.sendPort.send('任務(wù)隊列2');
  receivePort.sendPort.send('任務(wù)隊列3');
  Future.microtask(() {
    print('微任務(wù)1');
  });
  Future.microtask(() {
    print('微任務(wù)1');
  });
  Future.microtask(() {
    print('微任務(wù)1');
  });
  receivePort.listen((t) {
    print(t);
  });
}

同Android Handler類似,在Dart運行環(huán)境中也是靠事件驅(qū)動的,通過event loop不停的從隊列中獲取消息或者事件來驅(qū)動整個應(yīng)用的運行,isolate發(fā)過來的消息就是通過loop處理。但是不同的是在Android中每個線程只有一個Looper所對應(yīng)的MessageQueue,而Dart中有兩個隊列,一個叫做event queue(事件隊列),另一個叫做microtask queue(微任務(wù)隊列)。

isolate數(shù)據(jù)通訊.png

? Dart在執(zhí)行完main函數(shù)后,就會由Loop開始執(zhí)行兩個任務(wù)隊列中的Event。首先Loop檢查微服務(wù)隊列,依次執(zhí)行Event,當微服務(wù)隊列執(zhí)行完后,就檢查Event queue隊列依次執(zhí)行,在執(zhí)行Event queue的過程中,沒執(zhí)行完一個Event就再檢查一次微服務(wù)隊列。所以微服務(wù)隊列優(yōu)先級高,可以利用微服務(wù)進行插隊。

我們先來看個例子:


import 'dart:io';


void main() {
  new File("abc.txt").readAsString().then((t) {
    print(t);
  });

  while (true) {}
}

疑問:這個方法能夠打印出來嗎?

異步編程(Future 和 async-await)

Future(flutter中重要的一個異常調(diào)用)

? 在 Dart 庫中隨處可見 Future 對象,通常異步函數(shù)返回的對象就是一個 Future。 當一個 future 執(zhí)行完后,他里面的值 就可以使用了,可以使用 then() 來在 future 完成的時候執(zhí)行其他代碼。Future對象其實就代表了在事件隊列中的一個事件的結(jié)果。

組合

then()的返回值同樣是一個future對象,可以利用隊列的原理進行組合異步任務(wù)

  import 'dart:io';


void main() {
  new File("abc.txt").readAsString().then((t) {
    print(t);
    return 100;
  }).then((t) {
    print(t);
  });
}

上面的方式是等待執(zhí)行完成讀取文件之后,再執(zhí)行一個新的future。如果我們需要等待一組任務(wù)都執(zhí)行完成再統(tǒng)一處理一些事情,可以通過wait()完成。

 import 'dart:io';

void main() {
  Future future = new File("abc.txt").readAsString();

  Future future2 = Future.delayed(Duration(seconds: 3));

  Future.wait([future, future2]).then((values) {
    print(values[0]);
    print(values[1]);
  });
}

async/await

? 使用asyncawait的代碼是異步的,但是看起來很像同步代碼。當我們需要獲得A的結(jié)果,再執(zhí)行B,時,你需要then()->then(),但是利用asyncawait能夠非常好的解決回調(diào)地獄的問題:

//async 表示這是一個異步方法,await必須再async方法中使用
//異步方法只能返回 void和Future
import 'dart:io';


void main() {
  readNet().then((t) {
    print(t);
  });
}

Future<String> readNet() async {
  String str1 = await new File("abc.txt").readAsString();
  String str2 = await new File("123.txt").readAsString();
  return "$str1 $str2";
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容