一,概述
在Dart1.9中加入了async和await關鍵字,有了這兩個關鍵字,我們可以更簡潔的編寫異步代碼,而不需要調用Future相關的API。他們允許你像寫同步代碼一樣寫異步代碼和不需要使用Future接口。相當於都Future相關API接口的另一種封裝,提供了一種更加簡便的操作Future相關API的方法
將 async 關鍵字作為方法聲明的后綴時,具有如下意義
- 被修飾的方法會將一個 Future 對象作為返回值
- 該方法會同步執行其中的方法的代碼直到第一個 await 關鍵字,然后它暫停該方法其他部分的執行;
- 一旦由 await 關鍵字引用的 Future 任務執行完成,await的下一行代碼將立即執行。
二,Async/await 示例解析
- 示例一:
使用Async/await
也是可以實現異步操作,下面直接上例子:
main() { create(); }
void create(){ String data = getData(); print(data); print("I love Future"); }
getData() async{ return await "I love Android"; }
運行上面代碼,報錯了:
type 'Future<dynamic>' is not a subtype of type 'String'
報的是類型不匹配?為什么呢?經過一番搜查,發現
getData
是一個異步操作函數,它的返回值是一個await
延遲執行的結果。在Dart
中,有await
標記的運算,其結果值是一個Future
對象,Future
並不是String類型,就報錯了。那么怎么才正確獲得異步的結果呢?Dart規定async標記的函數,只能由await來調用,下面改成這樣:main() { create(); } void create() async{ String data = await getData(); print(data); print("I love Future"); }
getData() async{ return await "I love Android"; }下面直接去掉
async
函數包裝,直接在getData
方法里對data
進行賦值:String data; main() { create(); }
void create(){ getData(); print("I love Future"); }
getData() async{ data = await "I love Android"; print(data); }上面輸出結果是:
I love Future I love Android
可以發現,先輸出的是
I love Future
后面再輸出I love Android
,可以發現當函數被async
修飾時,會先去執行下面的操作,當下面的操作執行完,然后再執行被async
修飾的方法。async
用來表示函數是異步的,定義的函數會返回一個Future
對象,await
后面是一個Future
,表示等待該異步任務完成,異步完成后才會往下走。要注意以下幾點: - await關鍵字必須在async函數內部使用,也就是加await不加async會報錯。
- 調用async函數必須使用await關鍵字,如果加async不加await會順序執行代碼。
PS: await 關鍵字真的很形象,等一等的意思,就是說,既然你運行的時候都要等一等,那我調用的時候也要等等吧。
- 示例二:
main() { _startMethod(); _method_C(); } _startMethod() async{ _method_A(); await _method_B(); print("start結束"); }
_method_A(){ print("A開始執行這個方法~"); } _method_B() async { print("B開始執行這個方法~"); await print("后面執行這句話~"); print("繼續執行這句哈11111~"); } _method_C(){ print("C開始"); }
結果如下:
A開始執行這個方法~ B開始執行這個方法~ 后面執行這句話~ C開始 繼續執行這句哈11111~ start結束
過程分析:
-
- 當使用async作為方法名后綴聲明時,說明這個方法的返回值是一個Future;
- 當執行到該方法代碼用await關鍵字標注時,會暫停該方法其他部分執行;
- 當await關鍵字引用的Future執行完成,下一行代碼會立即執行。
也就是首先執行_startMethod
這個方法用async聲明了,因為方法里調用了_method_A
,所以先輸出print("A開始執行這個方法~");,后面執行_method_B()
,這個方法用await關鍵字聲明,所以會暫停print("start結束");的執行,然后繼續執行_method_B()
將print("B開始執行這個方法~");輸出,下一行遇到await關鍵字,會暫停其他代碼的執行。當await關鍵字引用的Future執行完成(也就是執行print("后面執行這句話~"),_method_C()
方法會立即執行,然后執行繼續執行這句哈11111~,最后執行print("start結束");