【Flutter 面试题】在flutter里streams是什么?有几种streams?有什么场景用到它?

写在前面

关于我 ,小雨青年 👉 CSDN博客专家,GitChat专栏作者,阿里云社区专家博主,51CTO专家博主。2023博客之星TOP153。

👏🏻 正在学 Flutter 的同学,你好!

😊 本专栏是解决 Flutter 面试过程中可能出现的问题,而进行汇总整理的。一个问题一篇文章,尽可能详细解答,满足面试需求。

🔍 想解决开发中的零散问题?碎片化教程 👉 Flutter Tips

🔍 想深入学习 Flutter?系统化教程 👉 Flutter 从零到一 基础入门到应用上线全攻略 & 专栏指引

👥 快来和我们一起交流!👉 讨论群在这里,和大家一起进步!

解答

在Flutter中,Streams是一种处理异步数据流的方式。它可以被比喻为一个可以随时间持续传递数据的管道。

当你需要处理一系列随时间变化的数据,比如用户的输入、文件的读取或者网络请求的响应时,Streams就特别有用。

Flutter中主要有两种类型的Streams:

  1. Single subscription streams:这种Stream只能有一个监听器,一旦有人开始监听它,就不能再有其他的监听器加入了。这种Stream适合处理一次性的事件,比如一个文件的下载。

  2. 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

运行结果如下

【Flutter 面试题】在flutter里streams是什么?有几种streams?有什么场景用到它?-LMLPHP

广播流 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();
  });
}

运行结果如下

【Flutter 面试题】在flutter里streams是什么?有几种streams?有什么场景用到它?-LMLPHP

03-05 11:32