【Flutter 面试题】在flutter里streams是什么?有几种streams?有什么场景用到它?
写在前面
关于我 ,小雨青年 👉 CSDN博客专家,GitChat专栏作者,阿里云社区专家博主,51CTO专家博主。2023博客之星TOP153。
👏🏻 正在学 Flutter 的同学,你好!
😊 本专栏是解决 Flutter 面试过程中可能出现的问题,而进行汇总整理的。一个问题一篇文章,尽可能详细解答,满足面试需求。
🔍 想解决开发中的零散问题?碎片化教程 👉 Flutter Tips。
🔍 想深入学习 Flutter?系统化教程 👉 Flutter 从零到一 基础入门到应用上线全攻略 & 专栏指引。
👥 快来和我们一起交流!👉 讨论群在这里,和大家一起进步!
解答
在Flutter中,Streams是一种处理异步数据流的方式。它可以被比喻为一个可以随时间持续传递数据的管道。
当你需要处理一系列随时间变化的数据,比如用户的输入、文件的读取或者网络请求的响应时,Streams就特别有用。
Flutter中主要有两种类型的Streams:
-
Single subscription streams:这种Stream只能有一个监听器,一旦有人开始监听它,就不能再有其他的监听器加入了。这种Stream适合处理一次性的事件,比如一个文件的下载。
-
Broadcast streams:这种Stream可以被多个监听器同时监听。这对于多个组件需要响应同一个数据源的情况非常有用,比如用户的操作或者数据的实时更新。
Streams在Flutter中的一些常见使用场景包括:
- 用户输入处理:比如监听文本框的变化,你可以使用Stream来捕获用户的每次输入,然后根据这些输入做出响应。
- 网络请求:当你从网络获取数据时,数据的接收是异步的,你可以使用Stream来监听数据的到来,并在数据到来时更新UI。
- 文件操作:读取或写入文件时,数据的处理也是异步的,通过Stream你可以在数据读写时进行实时的处理和更新。
- 实时数据更新:在需要处理如股票行情或聊天应用中的实时数据更新时,使用Broadcast streams可以让多个组件监听并响应同一个数据源的变化。
Streams提供了一种灵活的方式来处理Flutter应用中的异步数据流,无论是单一数据的一次性处理还是多源数据的实时更新,Streams都能提供有效的解决方案。
补充说明
为了让你更好地理解 Streams ,我们直接上代码。
Single subscription streams 读取文件
接下来我们用一个简单的例子,这段代码会逐行读取 file.txt
文件,并在控制台中打印出每一行的内容。当文件全部读取完毕时,它会打印一条消息表示文件已关闭。
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void readFileWithSingleSubscriptionStream(String filePath) {
// 创建一个指向文件的引用
File file = File(filePath);
// 打开文件流
Stream<List<int>> inputStream = file.openRead();
// 使用单订阅流监听数据
inputStream
.transform(utf8.decoder) // 将字节流转换为 UTF-8 字符串
.transform(LineSplitter()) // 按行分割字符串
.listen(
(String line) {
// 处理每一行数据
print('Got line: $line');
},
onDone: () {
// 文件读取完成
print('File is now closed.');
},
onError: (e) {
// 处理可能发生的错误
print(e.toString());
},
);
}
void main() {
// 调用函数,读取文件
readFileWithSingleSubscriptionStream('../assets/file.txt');
}
我们直接执行 dart 文件。
dart run main.dart
运行结果如下
广播流 Broadcast streams 通知多个监听器关于状态的变化
广播流(Broadcast streams)在 Dart 中用于创建可以被多个监听器同时监听的流。这对于开发者来说非常有用,特别是当你想要多个部分的应用程序响应相同的数据变化时。下面是一个使用广播流的实际案例,其中我们将模拟一个简单的状态管理场景,使用广播流来通知多个监听器关于状态的变化。
在这个例子中,我们将创建一个 StatusNotifier
类,这个类将使用广播流来通知监听器有关状态更新。然后,我们将创建两个监听器来监听这些更新,并在控制台中打印状态更新。
import 'dart:async';
// 状态通知器类
class StatusNotifier {
// 私有的广播控制器
final _controller = StreamController<String>.broadcast();
// 获取广播流
Stream<String> get statusUpdates => _controller.stream;
// 更新状态的方法
void updateStatus(String newStatus) {
_controller.sink.add(newStatus);
}
// 关闭控制器的方法
void close() {
_controller.close();
}
}
void main() {
// 创建状态通知器实例
final notifier = StatusNotifier();
// 第一个监听器
notifier.statusUpdates.listen((status) {
print('Listener 1: Status updated to $status');
});
// 第二个监听器
notifier.statusUpdates.listen((status) {
print('Listener 2: Status updated to $status');
});
// 模拟状态更新
notifier.updateStatus('Processing');
Future.delayed(Duration(seconds: 1), () {
notifier.updateStatus('Completed');
});
// 给一些时间来处理异步操作
Future.delayed(Duration(seconds: 2), () {
// 关闭状态通知器
notifier.close();
});
}
运行结果如下