跟我學flutter:我們來舉個例子通俗易懂講解非同步(一)ioslate

語言: CN / TW / HK

前言

Dart是單執行緒的,Dart提供了Isolate,isolate提供了多執行緒的能力。但作為多執行緒能力的,卻記憶體不能共享。但同樣的記憶體不能共享,那麼就不存在鎖競爭問題。

舉個例子來展示作用

如果一段程式碼執行事件很長,flutter如何開發。 基本頁面程式碼(一段程式碼)

bash ElevatedButton( child: Text("登入"), onPressed: () { 執行執行程式碼(); } 延時程式碼塊 bash String work(int value){ print("work start"); sleep(Duration(seconds:value)); print("work end"); return "work complete:$value"; }

第一種:直接執行執行程式碼(延時5秒)

bash 執行執行程式碼() { work(5); } 結果: 5秒卡的死死的

第二種:async執行執行程式碼(延時5秒)

bash 執行執行程式碼() async{ work(5); } 結果: 5秒依舊卡的死死的

------------------------------------------------我是分割線--------------------------------------------------

why?在dart中,async不是非同步計算麼?(迴圈機制下篇講)因為我們仍舊是在同一個UI執行緒中做運算,非同步只是說我可以先執行其他的,等我這邊有結果再返回,但是,我們的計算仍舊是在這個UI執行緒,仍會阻塞UI的重新整理,非同步只是在同一個執行緒的併發操作。

第三種:ioslate執行執行程式碼(延時5秒)

但是由於dart中的Isolate比較重量級,UI執行緒和Isolate中的資料的傳輸比較複雜,因此flutter為了簡化使用者程式碼,在foundation庫中封裝了一個輕量級compute操作。

bash 執行執行程式碼() async{ var result = await compute(work, 5); print(result); } 結果: 居然不卡頓了

使用說明

compute的使用還是有些限制,它沒有辦法多次返回結果,也沒有辦法持續性的傳值計算,每次呼叫,相當於新建一個隔離,如果呼叫過多的話反而會適得其反。我們需要根據不同的業務選擇用compute和isolate

```bash

Future work(int value) async{ //接收訊息管道 ReceivePort rp = new ReceivePort(); //傳送訊息管道 SendPort port = rp.sendPort; Isolate isolate = await Isolate.spawn(workEvent, port); //傳送訊息管道2 final sendPort2 = await rp.first; //返回應答資料 final answer = ReceivePort(); sendPort2.send([answer.sendPort, value]); return answer.first; }

void workEvent(SendPort port) { //接收訊息管道2 final rPort = ReceivePort(); SendPort port2 = rPort.sendPort; // 將新isolate中建立的SendPort傳送到主isolate中用於通訊 port.send(port2);

rPort.listen((message) { final send = message[0] as SendPort; send.send(work(5)); }); } ```

基本方法

```bash //恢復 isolate 的使用 isolate.resume(isolate.pauseCapability);

//暫停 isolate 的使用
isolate.pause(isolate.pauseCapability);

//結束 isolate 的使用
isolate.kill(priority: Isolate.immediate);

//賦值為空 便於記憶體及時回收
isolate = null;

```

兩個程序都雙向綁定了訊息通訊的通道,即使新的Isolate中的任務完成了,它的程序也不會立刻退出,因此,當使用完自己建立的Isolate後,最好呼叫isolate.kill(priority: Isolate.immediate);將Isolate立即殺死。

用Future還是isolate?

future使用場景:

  • 程式碼段可以獨立執行而不會影響應用程式的流暢性

isolate使用場景:

  • 繁重的處理可能要花一些時間才能完成
  • 網路載入大圖
  • 圖片處理