[英]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.