Flutter--Dart中的異步

以下內(nèi)容從官網(wǎng)得到:
https://webdev.dartlang.org/articles/performance/event-loop

Even-Looper

Dart是單線程模型,也就沒有了所謂的主線程/子線程之分。
Dart也是Event-Looper以及Event-Queue的模型,所有的事件都是通過EventLooper的依次執(zhí)行。

而Dart的Event Loop就是:

  • 從EventQueue中獲取Event
  • 處理Event
  • 直到EventQueue為空
Event Queue

而這些Event包括了用戶輸入,點(diǎn)擊,Timer,文件IO等

Event Type

單線程模型

一旦某個(gè)Dart的函數(shù)開始執(zhí)行,它將執(zhí)行到這個(gè)函數(shù)結(jié)束,也就是Dart的函數(shù)不會(huì)被其他Dart代碼打斷。

Dart中沒有線程的概念,只有isolate,每個(gè)isolate都是隔離的,并不會(huì)共享內(nèi)存。而一個(gè)Dart程序是在Main isolate的main函數(shù)開始,而在Main函數(shù)結(jié)束后,Main isolate線程開始一個(gè)一個(gè)(one by one)的開始處理Event Queue中的每一個(gè)Event。

Main Isolate

Event Queue以及Microtask Queue

Dart中的Main Isolate只有一個(gè)Event Looper,但是存在兩個(gè)Event Queue:Event Queue以及Microtask Queue

Microtask Queue存在的意義是:
希望通過這個(gè)Queue來處理稍晚一些的事情,但是在下一個(gè)消息到來之前需要處理完的事情。

當(dāng)Event Looper正在處理Microtask Queue中的Event時(shí)候,Event Queue中的Event就停止了處理了,此時(shí)App不能繪制任何圖形,不能處理任何鼠標(biāo)點(diǎn)擊,不能處理文件IO等等

Event-Looper挑選Task的執(zhí)行順序?yàn)椋?/p>

  • 優(yōu)先全部執(zhí)行完Microtask Queue中的Event
  • 直到Microtask Queue為空時(shí),才會(huì)執(zhí)行Event Queue中的Event
Microtask Queue && Event Queue

Dart中只能知道Event處理的先后順序,但是并不知道某個(gè)Event執(zhí)行的具體時(shí)間點(diǎn),因?yàn)樗奶幚砟P褪且粋€(gè)單線程循環(huán),而不是基于時(shí)鐘調(diào)度(即它的執(zhí)行只是按照Event處理完,就開始循環(huán)下一個(gè)Event,而與Java中的Thread調(diào)度不一樣,沒有時(shí)間調(diào)度的概念),也就是我們既是指定另一個(gè)Delay Time的Task,希望它在預(yù)期的時(shí)間后開始執(zhí)行,它有可能不會(huì)在那個(gè)時(shí)間執(zhí)行,需要看是否前面的Event是否已經(jīng)Dequeue。

異步任務(wù)調(diào)度

當(dāng)有代碼可以在后續(xù)任務(wù)執(zhí)行的時(shí)候,有兩種方式,通過dart:async這個(gè)Lib中的API即可:

  • 使用Future類,可以將任務(wù)加入到Event Queue的隊(duì)尾
  • 使用scheduleMicrotask函數(shù),將任務(wù)加入到Microtask Queue隊(duì)尾

當(dāng)使用EventQueue時(shí),需要考慮清楚,盡量避免microtask queue過于龐大,否則會(huì)阻塞其他事件的處理

Use Event Queue

使用Future

一般常用的Future構(gòu)造函數(shù):

new Future((){
    //  doing something
});

而一般常用的還有當(dāng)有分治任務(wù)時(shí),需要將一個(gè)大任務(wù)拆成很多小任務(wù)一步步執(zhí)行時(shí),就需要使用到Future.then函數(shù)來拆解任務(wù)

void main(){
new Future(() => futureTask)  //  異步任務(wù)的函數(shù)
        .then((m) => "futueTask execute result:$m")  //   任務(wù)執(zhí)行完后的子任務(wù)
        .then((m) => m.length)  //  其中m為上個(gè)任務(wù)執(zhí)行完后的返回的結(jié)果
        .then((m) => printLength(m))
        .whenComplete(() => whenTaskCompelete);  //  當(dāng)所有任務(wù)完成后的回調(diào)函數(shù)
}

int futureTask() {
    return 21; 
}

void printLength(int length) {
    print("Text Length:$length");
}

void whenTaskCompelete() {
    print("Task Complete");
}

當(dāng)任務(wù)需要延遲執(zhí)行時(shí),可以使用new Future.delay來將任務(wù)延遲執(zhí)行,而如上所述,只有當(dāng)Main isolate的Event Queue處于Idle的狀態(tài)時(shí),才會(huì)延遲1s執(zhí)行,否則等待的時(shí)間會(huì)比1s長很多

new Future.delayed(const Duration(seconds: 1), () => futureTask);

當(dāng)需要做動(dòng)畫的時(shí)候,不要使用Future,而需要使用animateFrame

PS:

  • Future中的then并沒有創(chuàng)建新的Event丟到Event Queue中,而只是一個(gè)普通的Function Call,在FutureTask執(zhí)行完后,立即開始執(zhí)行
  • 當(dāng)Future在then函數(shù)先已經(jīng)執(zhí)行完成了,則會(huì)創(chuàng)建一個(gè)task,將該task的添加到microtask queue中,并且該任務(wù)將會(huì)執(zhí)行通過then傳入的函數(shù)
  • Future只是創(chuàng)建了一個(gè)Event,將Event插入到了Event Queue的隊(duì)尾
  • 使用Future.value構(gòu)造函數(shù)的時(shí)候,就會(huì)和第二條一樣,創(chuàng)建Task丟到microtask Queue中執(zhí)行then傳入的函數(shù)
  • Future.sync構(gòu)造函數(shù)執(zhí)行了它傳入的函數(shù)之后,也會(huì)立即創(chuàng)建Task丟到microtask Queue中執(zhí)行

使用scheduleMicrotask

在最頂層的調(diào)用關(guān)系中,使用該函數(shù)即可

async.scheduleMicrotask(() => microtask());

void microtask(){
  //  doing something
}

使用isolate以及Worker

當(dāng)有計(jì)算很繁重的任務(wù)時(shí),則需要使用isolate或者Worker來執(zhí)行,以保持App對用戶操作的及時(shí)響應(yīng)。Isolate的實(shí)現(xiàn)可能是一個(gè)單獨(dú)的線程,或者一個(gè)單獨(dú)的進(jìn)程,需要看Dart VM是如何實(shí)現(xiàn)的。

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

相關(guān)閱讀更多精彩內(nèi)容

  • OC語言基礎(chǔ) 1.類與對象 類方法 OC的類方法只有2種:靜態(tài)方法和實(shí)例方法兩種 在OC中,只要方法聲明在@int...
    奇異果好補(bǔ)閱讀 4,532評論 0 11
  • 美圖欣賞 Java、Android知識(shí)點(diǎn)匯集 Java集合類 ** Java集合相關(guān)的博客** java面試相關(guān) ...
    ElvenShi閱讀 1,899評論 0 2
  • 客戶要求APP中所有數(shù)據(jù)的顯示和輸入使用類似銀行卡賬號(hào)字體,后來查資料發(fā)現(xiàn)需要自定義字體,在使用自定義字體之前需要...
    沉默的魚sunny閱讀 3,527評論 0 0
  • 問題 在vivo X5Pro手機(jī)上,點(diǎn)擊微博登錄時(shí)出現(xiàn)崩潰。經(jīng)過分析發(fā)現(xiàn)是微博依賴的so庫在該設(shè)備上缺失導(dǎo)致的。 ...
    亞克西閱讀 1,078評論 0 0
  • 從上周二開始,嗓子難受,可感冒卻一直隱忍不發(fā)。直到昨天終于如火山一般噴涌而出了,燒38.7度。這是有史以來最高溫。...
    依心室閱讀 235評論 0 1

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