爲何 Dart 是單線程的語言卻能支持異步?

在開始弄懂問題以前咱們先來了解下兩個很是重要的東西:ios

isolateevent loop算法

Isolate

若是你已經看過官方文檔,相信已經對 isolate 有了必定的瞭解,這裏,我想再從新講一下。網絡

ioslate 被翻譯成中文是隔離器的意思,下文會統稱爲隔離器app

隔離器咱們從字面上能夠隱約感知到,它是一個單獨的被隔離的器皿。是的,在Dart中,它就是這麼一個被隔離的東西。異步

那麼隔離的東西里面有什麼呢?函數

它有一塊本身的內存(Memory)以及一個單獨的線程(Thread)。oop

那這個線程是幹嗎的呢?spa

答案: 它一直在運行事件循環(Event Loop)線程

以下圖所示:翻譯

隔離器是否是惟一的?

在 Dart app 中隔離器不是惟一的,能夠手動建立多個隔離器。

利用 Isolate.spawn() 或者 Flutter 中的 compute() 來建立多個隔離器。

爲何要建立多個隔離器?

試想一下,若是隻有一個隔離器,那麼作龐大計算時是否是很容易形成掉幀(計算密集型操做會讓 App 卡頓)

固然也能夠從上面兩個建立隔離器的函數名中看出端倪。

建立出的隔離器與原先的隔離器相互之間不能訪問各自的內存及線程,它們只有一種交互模式

經過互相傳遞消息,A 隔離器發送一條消息給 B 隔離器,B 隔離器接收到消息後利用本身的事件循環來處理消息。

這樣的好處是,可以不用鎖定隔離器中的內存分配及垃圾回收,由於只有一個線程,因此很容易就能知道內存有沒有被修改(由於沒有別的線程能訪問這塊內存空間),在 Flutter 中,對快速構建或拆除一個界面中的部分組件特別有效。

Event loop

上文中已經有提到事件循環,相信你已經對它有點印象了,它會負責處理收到的消息事件,固然它也是讓 Dart 可以真正擁有異步能力的核心。

1. 事件循環是幹嗎用的?

在一個 app 中,啓動,退出,用戶會點擊,滑動,程序訪問硬盤等等,這一系列的操做咱們統稱爲事件,由於你不知道事件什麼時候會發送過來,因此得有一個永不停歇不能阻塞的循環來等待處理事件。

2. 事件循環的運行機制

事件被被扔到一個事件隊列中,而事件循環會從事件隊列中取出最舊的事件處理,再返回下一個事件處理,以此類推直到事件隊列中再也沒有事件了。

當處理事件操做中存在一箇中斷(break),線程會先掛出,等待下一個事件。

3. 到底怎麼異步啊?

相信絕大多數人看到這裏仍是沒有想通爲何,綜上,我就來說解一下。

首先一個App從啓動到關閉,絕大部分的時間都在等待中。 例如:等待用戶操做,網絡請求等等。

那麼這種等待是否是阻塞的呢?確定不是咯,不然還怎麼玩!

剛纔說了事件循環是永不停歇的,A 事件處理完後悔處理 B 事件,B 事件處理完了要處理 C事件。

這裏傳遞的事件都不可以是阻塞型的事件,不然會形成 ANR,耗時操做記得使用異步對象。

Dart 中提供了一異步對象例如:FutureStream他們都是非阻塞的。

這些異步對象都會告訴事件循環說:待會來執行代碼,你先忙你的。

這樣子就造成了一個異步的機制。

總結

本文淺出了 Dart 單線程語言中如何實現異步,若是你對異步還有相關疑問,歡迎關注咱們的公衆號:算法詳解

按期更新 Dart 技術乾貨。

相關文章
相關標籤/搜索