簡體   English   中英

Dart/Flutter - 回調函數中的“yield”

[英]Dart/Flutter - "yield" inside a callback function

我需要為一個函數生成一個列表; 但是,我想從回調函數中生成列表,該回調函數本身位於主函數內部 - 這導致 yield 語句不是為主函數執行,而是為回調函數執行。

我的問題與這里解決的問題非常相似: Dart Component: How to return result of asynchronous callback? 但我不能使用 Completer,因為我需要讓步而不是返回。

下面的代碼應該更好地描述問題:

Stream<List<EventModel>> fetchEvents() async* { //function [1]
    Firestore.instance
        .collection('events')
        .getDocuments()
        .asStream()
        .listen((snapshot) async* { //function [2]
      List<EventModel> list = List();
      snapshot.documents.forEach((document) {
        list.add(EventModel.fromJson(document.data));
      });

      yield list; //This is where my problem lies - I need to yield for function [1] not [2]
    });
  }

而不是.listen處理另一個函數內的事件,您可以使用await for來處理外部函數內的事件。

另外-當您產生仍在內部流回調中填充的List實例時,您可能需要重新考慮該模式...

Stream<List<EventModel>> fetchEvents() async* {
  final snapshots =
      Firestore.instance.collection('events').getDocuments().asStream();
  await for (final snapshot in snapshots) {
    // The `await .toList()` ensures the full list is ready
    // before yielding on the Stream
    final events = await snapshot.documents
        .map((document) => EventModel.fromJson(document.data))
        .toList();
    yield events;
  }
}

我想在這里添加一個改進建議。 在某些情況下應該避免建議的await for解決方案,因為它是不可關閉的偵聽器,並且它更新停止偵聽,因此這可能導致內存泄漏。 您也可以使用.map像這樣轉換流產生結果(沒有嘗試編譯它,但主要思想應該很清楚):

Stream<List<EventModel>> fetchEvents() { // remove the async*
    Firestore.instance
        .collection('events')
        .getDocuments()
        .asStream()
        .map((snapshot) { // use map instead of listen
      List<EventModel> list = List();
      snapshot.documents.forEach((document) {
        list.add(EventModel.fromJson(document.data));
      });

      return list; // use return instead of yield
    });
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM