我有一个流从Web api返回值,而一个小部件显示一个值(使用FutureBuilder)。用户可以使用一个简单的下一个按钮迭代这些值。我不想预先加载所有值,但是我不想在按下下一步按钮时加载每个值。
我当前的代码是:
Queue<Item> itemQueue = Queue<Item>();
Future<Item> curItem;
Future<Item> getItem() async {
while (itemQueue.isEmpty)
await Future.delayed(Duration(milliseconds: 250));
return itemQueue.removeFirst();
}
@override
void initState() {
// ...
final sub = stream.listen((item) async {
itemQueue.add(item);
});
// ...
}
@override
Widget build(BuildContext context) {
// ...
ItemWidget(curItem)
// ...
RaisedButton(child: Text("next"),
onPressed: (){
setState(() {
curItem = getItem();
});
},)
// ...
}
这种方法有效,但感觉这不是最正确/最优雅的方法。
有没有更好的办法?
谢谢!
最佳答案
编辑:
正如评论中指出的那样,创建广播流的原始答案可能会导致事件掉在地板上。为了避免创建广播流,我们可以使用StreamIterator一次遍历流中的一个元素:
final myStream = Stream.fromIterable([1,2,3,4,5]);
// We need to be able to listen to the stream multiple times.
final iter = StreamIterator(myStream);
// The iterator doesn't start at the first element, so we need to
// do that ourselves.
while (await iter.moveNext()) {
// StreamIterator.current will always point to the currently selected
// element of the stream.
print(iter.current);
}
原文:
您应该能够使用Stream.asBroadcastStream和Stream.take来执行此操作。
您的代码如下所示:
final myStream = Stream.fromIterable([1,2,3,4,5]);
// We need to be able to listen to the stream multiple times.
final stream = myStream.asBroadcastStream();
for (int i = 0; i < 5; ++i) {
// Creates a new Stream with 1 element which we can call Stream.first on
// This also changes the contents of stream.
print(await stream.take(1).first);
}
哪个会输出:
1
2
3
4
5
关于flutter - 从流一一获得 future ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59888242/