淺析Dart語(yǔ)言的異步處理
何為異步支持
了解一下異步線程
- 為何有異步?
- Dart是單線程語(yǔ)言,當(dāng)其遇到有延遲的運(yùn)算(比如IO操作、延時(shí)執(zhí)行)時(shí),線程中按順序執(zhí)行的運(yùn)算就會(huì)阻塞,用戶就會(huì)感覺到卡頓,因此通常用異步處理來(lái)解決線程阻塞問題。
- Dart單線程模型
- Dart 在單線程中是以消息循環(huán)機(jī)制來(lái)運(yùn)行的,其中包含兩個(gè)任務(wù)隊(duì)列,一個(gè)是“微任務(wù)隊(duì)列” microtask queue,另一個(gè)“事件隊(duì)列” event queue。
- Dart線程運(yùn)行
- Dart線程運(yùn)行過程,入口函數(shù) main() 執(zhí)行完后,消息循環(huán)機(jī)制便啟動(dòng)了。
- 首先會(huì)按照先進(jìn)先出的順序逐個(gè)執(zhí)行微任務(wù)隊(duì)列中的任務(wù),當(dāng)所有微任務(wù)隊(duì)列執(zhí)行完后便開始執(zhí)行事件隊(duì)列中的任務(wù),事件任務(wù)執(zhí)行完畢后再去執(zhí)行微任務(wù),如此循環(huán)往復(fù)。
Dart中支持異步編程的方式
- 異步函數(shù):Future和Stream
- 關(guān)鍵字
async
和await
也支持異步編程
使用 async 和 await 進(jìn)行異步處理
- 先看一個(gè)案例:
/*返回值為Future<String>類型,即其返回值未來(lái)是一個(gè)String類型的值*/ /*async關(guān)鍵字聲明該函數(shù)內(nèi)部有代碼需要延遲執(zhí)行*/ getData() async { /*await關(guān)鍵字聲明運(yùn)算為延遲執(zhí)行,然后return運(yùn)算結(jié)果*/ return await "This is a doubi"; }
- 調(diào)用這個(gè)方法,并獲取返回值??刂婆_(tái)居然報(bào)錯(cuò)
String data = getData();
- 報(bào)錯(cuò)原因
- data是String類型,而函數(shù)getData()是一個(gè)異步操作函數(shù),其返回值是一個(gè)await延遲執(zhí)行的結(jié)果。在Dart中,有await標(biāo)記的運(yùn)算,其結(jié)果值都是一個(gè)Future對(duì)象,F(xiàn)uture不是String類型,所以報(bào)錯(cuò)。
- 總結(jié)一下:
- 獲取異步方法中直接 return await .. .時(shí),實(shí)際上返回的是一個(gè)延遲計(jì)算的Future對(duì)象。
- 兩點(diǎn)需要注意:
- await關(guān)鍵字必須在async函數(shù)內(nèi)部使用
- 調(diào)用async函數(shù)必須使用await關(guān)鍵字
Future是什么
與JavaScript中的
Promise
非常相似,表示一個(gè)異步操作的最終完成(或失?。┘捌浣Y(jié)果值的表示。就是用于處理異步操作的,異步處理成功了就執(zhí)行成功的操作,異步處理失敗了就捕獲錯(cuò)誤或者停止后續(xù)操作。
- Future表示一件“將來(lái)”會(huì)發(fā)生的事情,將來(lái)可以從Future中取到一個(gè)值。當(dāng)一個(gè)方法返回一個(gè)Future時(shí),發(fā)生兩件事情:
- 將某件事情排隊(duì),返回一個(gè)未完成的Future
- 事情完畢之后,F(xiàn)uture的狀態(tài)會(huì)變成已完成,此時(shí)就可以取到這件事情的返回值。
- Future表示一件“將來(lái)”會(huì)發(fā)生的事情,將來(lái)可以從Future中取到一個(gè)值。當(dāng)一個(gè)方法返回一個(gè)Future時(shí),發(fā)生兩件事情:
獲取Future返回值,兩種方式:
- 使用async配合await
- 使用Future提供的api,其實(shí)就是用Future的then方法獲取返回值
Future示例
void doAsyncs() async{ //then catchError whenComplete new Future(() => futureTask()) // 異步任務(wù)的函數(shù) .then((m) => "1-:$m") // 任務(wù)執(zhí)行完后的子任務(wù) .then((m) => print('2-$m')) // 其中m為上個(gè)任務(wù)執(zhí)行完后的返回的結(jié)果 .then((_) => new Future.error('3-:error')) .then((m) => print('4-')) .whenComplete(() => print('5-')) //不是最后執(zhí)行whenComplete,通常放到最后回調(diào) .catchError((e) => print('6-catchError:' + e), test: (Object o) { print('7-:' + o); return true; //返回true,會(huì)被catchError捕獲 }) .then((_) => new Future.error('11-:error')) .then((m) => print('10-')) .catchError((e) => print('8-:' + e)) ; } futureTask() { return Future.delayed(Duration(seconds: 5),() => "9-走去跑步"); }
- 執(zhí)行結(jié)果
I/flutter: 2-1-:9-走去跑步
I/flutter: 5-
I/flutter: 7-:3-:error
I/flutter: 6-catchError:3-:error
I/flutter: 8-:11-:error
介紹一下Async/await
- Dart中的
async/await
- 和JavaScript中的
async/await
功能和用法是一樣的。
- 和JavaScript中的
async/await消除callback hell
- 代碼如下:
task() async { try{ String id = await login("alice","******"); String userInfo = await getUserInfo(id); await saveUserInfo(userInfo); //執(zhí)行接下來(lái)的操作 } catch(e){ //錯(cuò)誤處理 print(e); } }
async
用來(lái)表示函數(shù)是異步的- 定義的函數(shù)會(huì)返回一個(gè)
Future
對(duì)象,可以使用then方法添加回調(diào)函數(shù)。
- 定義的函數(shù)會(huì)返回一個(gè)
await
后面是一個(gè)Future
- 表示等待該異步任務(wù)完成,異步完成后才會(huì)往下走;
await
必須出現(xiàn)在async
函數(shù)內(nèi)部。
- 表示等待該異步任務(wù)完成,異步完成后才會(huì)往下走;
Stream是什么
Stream
同樣是用于接收異步事件數(shù)據(jù),和Future
的區(qū)別是,它可以接收多個(gè)異步操作的結(jié)果(成功或失?。?。- 在執(zhí)行異步任務(wù)時(shí),可以通過多次觸發(fā)成功或失敗事件來(lái)傳遞結(jié)果數(shù)據(jù)或錯(cuò)誤異常。
Stream應(yīng)用示例
Stream
常用于會(huì)多次讀取數(shù)據(jù)的異步任務(wù)場(chǎng)景,如網(wǎng)絡(luò)內(nèi)容下載、文件讀寫等:
Stream.fromFutures([ // 1秒后返回結(jié)果 Future.delayed(new Duration(seconds: 1), () { return "hello 1"; }), // 拋出一個(gè)異常 Future.delayed(new Duration(seconds: 2),(){ throw AssertionError("Error"); }), // 3秒后返回結(jié)果 Future.delayed(new Duration(seconds: 3), () { return "hello 3"; }) ]).listen((data){ print(data); }, onError: (e){ print(e.message); },onDone: (){ print("完成"); });
- 依次會(huì)輸出:
I/flutter (17666): hello 1
I/flutter (17666): Error
I/flutter (17666): hello 3
到此這篇關(guān)于淺析Dart語(yǔ)言的異步處理的文章就介紹到這了,更多相關(guān)Dart 異步處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Dart多個(gè)future隊(duì)列完成加入順序關(guān)系及原子性論證
這篇文章主要介紹了Dart多個(gè)future隊(duì)列完成加入順序關(guān)系及原子性論證,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11一文詳解Dart如何實(shí)現(xiàn)多任務(wù)并行
這篇文章主要為大家介紹了Dart如何實(shí)現(xiàn)多任務(wù)并行示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Android開發(fā)中Dart語(yǔ)言7個(gè)很酷的特點(diǎn)
這篇文章主要為大家介紹了Android開發(fā)中Dart語(yǔ)言7個(gè)很酷的特點(diǎn)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Flutter入門學(xué)習(xí)Dart語(yǔ)言變量及基本使用概念
這篇文章主要為大家介紹了Flutter入門學(xué)習(xí)Dart語(yǔ)言變量及基本使用概念,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09谷歌Sky語(yǔ)言怎么樣?什么是Dart編程語(yǔ)言?
據(jù)外媒報(bào)道,在日前舉行Dart開發(fā)者峰會(huì)上,谷歌對(duì)外正式展示了Android最新的開發(fā)語(yǔ)言Sky,據(jù)悉,Sky本質(zhì)上就是谷歌自主的網(wǎng)頁(yè)開發(fā)語(yǔ)言Dart.2015-05-05Flutter 語(yǔ)法進(jìn)階抽象類和接口本質(zhì)區(qū)別詳解
這篇文章主要為大家介紹了Flutter 語(yǔ)法進(jìn)階抽象類和接口本質(zhì)區(qū)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08