[譯] Dart非同步之Isolates 和event loops

fgyong發表於2020-07-28

Dart是一個單執行緒的語言,它提供了futurestreambackground wotk、和其他的事件、非同步,對於Flutter而言,本章節講解了Dart的後臺工作基礎:隔離和事件迴圈。

Isolates

所有Dart程式碼都在其中執行隔離程式。它就像是機器上的一個小空間,具有自己的私有記憶體塊和一個執行事件迴圈的單個執行緒。

[譯] Dart非同步之Isolates 和event loops

在許多其他語言(例如C ++)中,您可以讓多個執行緒共享相同的記憶體並執行所需的任何程式碼。但是,在Dart中,每個執行緒都處於其自己的隔離區中,並擁有自己的記憶體,並且該執行緒僅處理事件(一分鐘內會處理更多事件)。

許多Dart應用程式都在單個隔離中執行所有程式碼,但是如果需要,您可以擁有多個。如果要執行的計算量如此之大,以至於如果它在主隔離中執行,可能會導致丟幀,那麼可以使用Isolate.spawn()Fluttercompute()函式。這兩個函式都建立了一個單獨的隔離程式來處理數字,使您的主要隔離程式可以自由地(例如)重建和渲染小部件樹。

兩個isolates,他們分別有自己的記憶體和執行緒

新隔離區擁有自己的事件迴圈和記憶體,即使原始隔離區是該新隔離區的父級,也不允許其訪問。這就是孤立的名稱:這些小空間彼此隔離。

實際上,隔離器可以一起工作的唯一方法是通過來回傳遞訊息。一個隔離向另一個傳送訊息,接收隔離使用其事件迴圈處理該訊息。

[譯] Dart非同步之Isolates 和event loops

缺少共享記憶體聽起來可能很嚴格,尤其是如果您使用的是JavaC ++之類的語言時,但這對Dart編碼人員來說有一些關鍵的好處。

例如,隔離中的記憶體分配和垃圾回收不需要鎖定。只有一個執行緒,因此,如果不很忙,您就知道記憶體沒有被更改。這對於Flutter應用程式來說效果很好,有時需要快速構建和拆除一堆小部件。

Event loops

現在,您已經對隔離有了基本的介紹,讓我們深入研究真正使非同步程式碼成為可能的事情:事件迴圈。 想象一下,應用程式的生命週期在時間軸上延伸。該應用程式啟動,該應用程式停止,並且在一系列事件之間發生–來自磁碟的I/O,來自使用者的手指敲擊……各種各樣的東西。 您的應用無法預測這些事件何時發生或以什麼順序發生,因此必須使用一個永不阻塞的執行緒來處理所有這些事件。因此,該應用執行一個事件迴圈。它從事件佇列中獲取最舊的事件,進行處理,返回到下一個事件,然後進行處理,依此類推,直到事件佇列為空。 應用程式在整個執行過程中-您在螢幕上點選,下載內容,計時器關閉-該事件迴圈不斷迴圈,一次處理一次這些事件。

[譯] Dart非同步之Isolates 和event loops

當操作中斷時,執行緒只會掛出,等待下一個事件。它可以觸發垃圾收集器,獲取咖啡,等等。 Dart用於非同步程式設計的所有高階API和語言功能(期貨,流,非同步和等待)都基於此簡單迴圈而構建。 例如,假設您有一個啟動網路請求的按鈕,如下所示:

RaisedButton(
  child: Text('Click me'),
  onPressed: () {
    final myFuture = http.get('https://example.com');
    myFuture.then((response) {
      if (response.statusCode == 200) {
        print('Success!');
      }
    });
  },
)
複製程式碼

當你啟動你的APPFlutter編譯這個button,然後渲染它,然後APP就開始等待事件。

您應用的事件迴圈只是閒著,等待下一個事件。與按鈕無關的事件可能會進入並得到處理,而按鈕坐在那裡等待使用者點選它。最終他們做到了,而點選事件進入了佇列。

該事件將被處理。 Flutter看著它,並且渲染系統說:“那些座標與凸起的按鈕匹配,”因此Flutter執行onPressed函式。該程式碼啟動一個網路請求(返回一個將來的請求),並使用then()方法註冊一個將來的完成處理程式。 而已。迴圈完成了該點選事件的處理,並且已將其丟棄。 現在,onPressedRaisedButton的一個屬性,並且網路事件將回撥用於將來,但是這兩種技術都在做相同的基本操作。它們都是告訴Flutter的一種方式,“嘿,稍後,您可能會看到一種特定型別的事件。當您這樣做時,請執行這段程式碼。” 因此,onPressed正在等待點選,而未來正在等待網路資料,但是從Dart的角度來看,這些都只是佇列中的事件。 這就是Dart中非同步編碼的工作方式。期貨,資料流,非同步和等待-這些API只是告訴您的方式 Dart的事件迴圈,“這裡有一些程式碼,請稍後執行。” 如果我們回顧一下該程式碼示例,您現在可以確切地看到它如何分解為特定事件的塊。 有初始版本(1),點選事件(2)和網路響應事件(3)。

RaisedButton( // (1)
  child: Text('Click me'),
  onPressed: () { // (2)
    final myFuture = http.get('https://example.com');
    myFuture.then((response) { // (3)
      if (response.statusCode == 200) {
        print('Success!');
      }
    });
  },
)
複製程式碼

習慣了使用非同步程式碼後,您將開始在各處識別這些模式。在繼續使用更高階別的API時,瞭解事件迴圈將有所幫助.

我們快速瞭解了Dart中的隔離,事件迴圈和非同步編碼的基礎。如果您要查詢更多詳細資訊,例如微任務佇列的工作方式,請參閱過時的,但仍備受喜愛的文章事件迴圈和Dart

原文:medium.com/dartlang/da…

翻譯 fgyong

日期 2020.7.28

相關文章