dart系列之:在dart中使用生成器

flydean發表於2021-11-23

簡介

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/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!

相關文章