異步是所有開發(fā)語言中非常重要的一環(huán),在執(zhí)行耗時操作的時候不會讓主線程長時間無響應(yīng),這一點在移動端開發(fā)中尤其重要
Dart庫中包含許多返回Future或Stream對象的函數(shù)。
這些函數(shù)是異步的:它們在設(shè)置可能耗時的操作(例如I / O)后返回,而不等待該操作完成。
Futures
async和await關(guān)鍵字支持異步編程,允許您編寫看起來類似于同步代碼的異步代碼。
await關(guān)鍵字在Dart2中才加入其中
使用異步的方法有兩個,第一個是使用await 另外一個是使用Future Api
使用async和await的代碼是異步的,但它看起來很像同步代碼。
例如,這里有一些代碼使用await來等待異步函數(shù)的結(jié)果:
await lookUpVersion();
要使用await關(guān)鍵字,需要在async包裹的代碼塊方法中使用
Future checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
注意:雖然異步函數(shù)可能執(zhí)行耗時的操作,但它不會等待這些操作。
相反,異步函數(shù)只在遇到第一個await表達(dá)式(詳細(xì)信息)時才會執(zhí)行。
然后它返回一個Future對象,僅在await表達(dá)式完成后才恢復(fù)執(zhí)行。
你也可以針對await進(jìn)行一個try catch 防止出現(xiàn)異常
try {
version = await lookUpVersion();
} catch (e) {
// React to inability to look up the version
}
你也可以多次使用await來執(zhí)行多次耗時操作
var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
以 async 關(guān)鍵字聲明的方法必須返回一個Future的對象,如果你需要返回一個有用的值,請將該對象加入到泛型里面
Future<String> lookUpVersion() async => '1.0.0';
Steam Api
當(dāng)您需要從Stream獲取值時,您有兩個選擇:使用async和異步for循環(huán)(等待)
或者使用Stream API,如庫瀏覽中所述。
注意:在使用await for前,請確保它使代碼更清晰,并且您確實希望等待所有流的結(jié)果。
例如,您通常不應(yīng)該使用await for UI事件偵聽器,因為UI框架會發(fā)送無窮無盡的事件流。
異步for循環(huán)具有以下形式:
await for (varOrType identifier in expression) {
// Executes each time the stream emits a value. 這個expression需要是一個事件流列表
}
表達(dá)式的值必須具有Stream類型。
執(zhí)行過程如下:
1.等到流發(fā)出一個值。
2.執(zhí)行for循環(huán)的主體,將變量設(shè)置為該發(fā)出的值。
3.重復(fù)1和2,直到關(guān)閉流。
要停止偵聽流,可以使用break或return語句,該語句會從for循環(huán)中斷開并從流中取消取消。
生成器
當(dāng)您需要懶加載一個序列的值時,請考慮使用生成器函數(shù)。Dart內(nèi)置支持兩種生成器功能:同步和異步
要實現(xiàn)同步生成器函數(shù),請將函數(shù)體標(biāo)記為sync *,并使用yield語句來傳遞值:
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
異步的寫法很類似,區(qū)別就在于關(guān)鍵字
Stream<int> asynchronousNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
如果您的生成器是遞歸的,則可以使用yield *來提高其性能:
Iterable<int> naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
可調(diào)用的類
如果你想你的類可以像方法一樣去調(diào)用的話,你需要在類里面增加一個call方法
