Dart/Flutter - "yield" 在回调函数中
Dart/Flutter - "yield" inside a callback function
我需要为一个函数生成一个列表;但是,我想从回调函数中生成列表,回调函数本身在主函数中 - 这导致 yield 语句不是针对主函数执行,而是针对回调函数执行。
我的问题与此处解决的问题非常相似: 但我不能使用 Completer,因为我需要屈服而不是 return。
下面的代码应该能更好地描述问题:
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]
});
}
您可以使用 await for
来处理外部函数内的事件,而不是在另一个函数内处理事件的 .listen
。
另外 - 当您产生 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
});
}
我需要为一个函数生成一个列表;但是,我想从回调函数中生成列表,回调函数本身在主函数中 - 这导致 yield 语句不是针对主函数执行,而是针对回调函数执行。
我的问题与此处解决的问题非常相似:
下面的代码应该能更好地描述问题:
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]
});
}
您可以使用 await for
来处理外部函数内的事件,而不是在另一个函数内处理事件的 .listen
。
另外 - 当您产生 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
});
}