亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

文章授權首發于code4flutter,如需轉載請注明來源 https://code4flutter.com/async-await-usage/

本文是flutter油管教程第3篇,介紹async和await的使用和原理

引言

很多語言使用async和await作為語法,將函數變成async,然后在代碼的某個位置,它會進行等待,直到任務處理完成返回。在flutter中也是這樣的基本功能,但是需要特別指出的是這種語法糖只是feature和stream的封裝,可以讓你更清晰的更易讀的代碼。

對比

「google教程」async/await的使用和原理

 

這里是一個處理數據處理的例子,網絡請求和文件IO操作是異步操作

我們想讓他們放在一起工作,首先通過網絡請求創建一個id,根據這個id進行網絡通信,然后用結果創建一個processdata的對象,使用dart的feature的api,然后將回調鏈接在一起。這樣用前一個的回調作為下一個回調的參數輸入,以此類推。但是之前的方式并不具有很好的可讀性,需要層層嵌套,但是用feature結合async和wait不一樣。

ProcessedData createData() async{
 final id = _loadFromDisk();
 final data = _fetchNetworkData(id);
 return ProcessedData(data);
}復制代碼

首先,添加async關鍵字,只是告訴編譯器,“嘿,我打算在這里使用await關鍵字”

接下來我們來添加await關鍵字,在每個feature之前,標志需要等待的函數,

最后,在返回值添加feature關鍵字,有人覺得很奇怪,為什么只是普通的返回處理數據結果的函數需要feature修飾呢,這是因為在processData之前有兩次異步操作用到了await。這意味著他開始執行,然后停止,等待磁盤事件,然后繼續,然后停下來等待網絡事件。只有在那之后才能提供一個值。代碼如下:

ProcessedData createData() async{
 final id = await _loadFromDisk();
 final data = await _fetchNetworkData(id);
 return ProcessedData(data);
}復制代碼

asyc/await 工作原理

所以當createData開始運行并觸發第一個await時,他才會返回一個feature,到調用函數,他說,“嘿,我需要等待一下東西”,這是一個空盒子,你需要等待一會兒,當我在網絡中等待的磁盤數據到達時,我將調用return語句并為你提供一些數據,把它放入futurebuilder,或其他東西中,這就是他的工作原理。用代碼翻譯如下:

Future<ProcessedData> createData(){
 return _loadFromDisk().then((id){
 return _fetchNetworkData(id);
}).then((data){
 return ProcessData(data);
})
}復制代碼

用feature api的好處就是你可以清楚的看到代碼是如何將事件進行拆分的。首先函數開始執行,調用loadfromdisk,等待來來自磁盤的數據觸發事件循環,然后第二個回調被調用,請求網絡,等待來自網絡的數據到達事件循環,然后處理數據。此時調用return,此時該值完成了。

「google教程」async/await的使用和原理

事件循環

現在我們使用async/await版本實現。通過await表達式作為等待。由此可以得到以下代碼。

async/await正確姿勢

Future<ProcessedData>createData() async{
 final id = await _loadFromDisk();
 final data = await _fetchNetworkData(id);
 return ProcessedData(data);
}復制代碼

createData開始執行,并觸發第一個等待,此時它將自己的future返回給函數,并調用loadFromDisk,然后像之前一樣,等待來自磁盤文件I/O事件,這樣就完成了由loadFromDisk返回的future,這意味著createData結束了等待,并可以繼續執行其余的代碼了。再次等待,請求網絡數據等待返回,最終網絡數據到達事件循環,這就完成了由fetchNetworkData返回的future。createData就可以再次繼續運行了,他創建并返回了一個ProcessedData的實例。他完成了createData在開頭處傳給調用者的那個future。

由此可以看到,相同的事件循環控制著代碼的運行,并涉及到相同的future,唯一變化的是,有了async/await,函數代碼變少了,看起來更像是同步的代碼。

async/await如何處理錯誤

普通的寫法,處理錯誤如下,

「google教程」async/await的使用和原理

 

使用catcherror來處理錯誤,完成后悔在最后執行回調,無論是否有錯誤發生。

在aync/await的方式中不用任何回調,而是用try catch

「google教程」async/await的使用和原理

 

可以使用try catch捕獲特定類型的異常,finally將在最后執行其代碼塊。

如何處理循環

如我們普通的循環寫法。用for來循環迭代值

int getTotal(List<int> numbers){
 int total = 0;
 for(final value in numbers){
 total +=value;
 }
 return total;
}復制代碼

但是如果我們這個函數讀取的是一個由數字組成的stream,該怎么辦,按照他們的異步到達的次序來進行求和,然后返回求和值,和aync awaite的方式一樣,不用改變代碼基本結構。

首先,先將函數標志位async

然后,將返回值更改為future

然后,在前面添加關鍵字await。完成。代碼如下:

Future<int> getTotal(List<int> numbers) async{
 int total = 0;
 await for(final value in numbers){
 total +=value;
 }
 return total;
}復制代碼

和future一樣,await關鍵字將我的函數,拆分為等待事件之前執行和之后執行,兩部分代碼,首先,他開始執行,一直到await,然后將其future返回給調用函數,并等待一段數據到達。當數據到達時,循環執行一次來處理那條數據,然后停下來,并等待下一條數據,也許此時應用程序會運行并執行其他一些操作,如垃圾回收,最終另一條數據到來了,然后循環再次執行,這種情況一直循環,直到stream結束并關閉,此時該函數退出循環,并執行其return語句。這樣就完成了getTotal在最初返回給它的調用者的feture。

有一點要注意的是,當你使用stream時,保證要處理的streams最終會完成。如果遇到如html查找一個按鈕點擊,這個按鈕一直沒出來就無法完成,則函數會一直等待的狀態。

參考

Get started with Flutter → flutter.dev Try a Flutter codelab → goo.gl/d3fHPo Join the conversation → goo.gl/68oUnb

分享到:
標簽:async await
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定