繁体   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