StreamProvider
StreamProvider
is similar to FutureProvider but for Streams instead of
Futures.
FutureProvider
与 Provider 类似,但用在 Stream 中而不是 Future。
StreamProvider
一般用于:
- 监听Firebase或web-sockets
- 每隔几秒重建另一个provider
由于 Stream 自然地公开了一种监听更新的方式,一些人可能认为使用 StreamProvider
没什么用。
特别是,你可能认为Flutter的 StreamBuilder 可以很好地用于监听流,但这是错误的。
在 StreamBuilder 上使用 StreamProvider
有很多好处:
- 它允许其他provider使用 ref.watch 监听流。
- 多亏了 AsyncValue ,它能确保加载和错误情况得到正确处理。
- 它消除了必须区分广播流和普通流的需要。
- 它缓存由流发出的最新值,确保如果在事件发出后添加监听器, 监听器仍然可以立即访问最新的事件。
- 它允许在测试期间通过覆盖
StreamProvider
轻松地模拟流。
用法示例:使用套接字的实时聊天
StreamProvider
用于处理异步数据流,如视频流、天气广播Api。
final chatProvider = StreamProvider<List<String>>((ref) async* {
// Connect to an API using sockets, and decode the output
final socket = await Socket.connect('my-api', 4242);
ref.onDispose(socket.close);
var allMessages = const <String>[];
await for (final message in socket.map(utf8.decode)) {
// A new message has been received. Let's add it to the list of all messages.
allMessages = [...allMessages, message];
yield allMessages;
}
});
然后,UI就可以像这样聊天了:
Widget build(BuildContext context, WidgetRef ref) {
final liveChats = ref.watch(chatProvider);
// Like FutureProvider, it is possible to handle loading/error states using AsyncValue.when
return switch (liveChats) {
// Display all the messages in a scrollable list view.
AsyncData(:final value) => ListView.builder(
// Show messages from bottom to top
reverse: true,
itemCount: value.length,
itemBuilder: (context, index) {
final message = value[index];
return Text(message);
},
),
AsyncError(:final error) => Text(error.toString()),
_ => const CircularProgressIndicator(),
};
}