簡介
ES6中在引入非同步程式設計的同時,也引入了Generators,通過yield關鍵詞來生成對應的資料。同樣的dart也有yield關鍵詞和生成器的概念。
什麼時候生成器呢?所謂生成器就是一個能夠持續產生某些資料的裝置,也叫做generator。
兩種返回型別的generator
根據是同步生成還是非同步生成,dart返回的結果也是不同的。
如果是同步返回,那麼返回的是一個Iterable物件.
如果是非同步返回,那麼返回的是一個Stream物件。
同步的generator使用sync*關鍵詞如下:
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
非同步的generator使用的是async* 關鍵詞如下:
Stream<int> asynchronousNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
生成關鍵詞使用的是yield。
如果yield後面跟著的本身就是一個generator,那麼需要使用yield*。
Iterable<int> naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
Stream的操作
stream表示的是流,得到這個流之後,我們需要從流中取出對應的資料。
從Stream中取出資料有兩種方式,第一種就是使用Stream本身的API來獲取Stream中的資料。
最簡單的就是呼叫stream的listen方法:
StreamSubscription<T> listen(void onData(T event)?,
{Function? onError, void onDone()?, bool? cancelOnError});
listen可以接資料的處理方法,具體使用如下:
final startingDir = Directory(searchPath);
startingDir.list().listen((entity) {
if (entity is File) {
searchFile(entity, searchTerms);
}
});
預設的方法是onData方法。
另外一種就是今天要講解的await for.
await for的語法如下:
await for (varOrType identifier in expression) {
// Executes each time the stream emits a value.
}
要注意的是上面的expression必須是一個Stream物件。並且await for必須用在async中,如下:
Future<void> main() async {
// ...
await for (final request in requestServer) {
handleRequest(request);
}
// ...
}
如果要想中斷對stream的監聽,則可以使用break或者return。
總結
以上就是dart中生成器的使用了。
本文已收錄於 http://www.flydean.com/13-dart-generators/
最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!