MST

星途 面试题库

面试题:Flutter中Future与Stream在异步数据加载场景下的比较与应用

在Flutter开发中,除了Future,Stream也常用于异步数据处理。请详细对比Future和Stream在异步数据加载场景下的特点、适用场景。假设你正在开发一个实时更新数据的Flutter应用,在哪些情况下你会优先选择Stream而不是Future,给出具体代码示例说明。
42.8万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

Future 和 Stream 在异步数据加载场景下的特点对比

  1. Future
    • 特点
      • 表示一个异步操作的最终结果,只能返回单个值。一旦 Future 完成(无论是成功还是失败),它就不会再产生新的值。
      • 适用于那些只需要获取一次异步操作结果的场景,例如网络请求获取单个数据对象、读取本地文件等。
    • 适用场景:数据获取操作只执行一次,并且期望在操作完成后立即得到结果。比如登录接口调用,只需要获取登录是否成功这一个结果。
  2. Stream
    • 特点
      • 可以在一段时间内异步地生成多个数据事件。它就像一个数据流,数据可以逐个产生并被监听。
      • 支持按事件驱动的方式处理数据,适合处理连续、实时的数据更新。例如来自传感器的数据、实时网络推送等。
    • 适用场景:需要持续监听数据变化或接收多个数据事件的场景,比如实时聊天消息、股票价格实时更新等。

实时更新数据应用中选择 Stream 的情况

在实时更新数据的 Flutter 应用中,当数据会不断变化且需要实时响应这些变化时,优先选择 Stream。例如,实时获取设备电池电量变化的场景:

import 'dart:async';
import 'package:flutter/material.dart';

class BatteryLevelStream extends StatefulWidget {
  @override
  _BatteryLevelStreamState createState() => _BatteryLevelStreamState();
}

class _BatteryLevelStreamState extends State<BatteryLevelStream> {
  StreamSubscription<int>? _subscription;
  int _batteryLevel = 0;

  @override
  void initState() {
    super.initState();
    // 模拟获取电池电量的 Stream
    final batteryLevelStream = Stream.periodic(const Duration(seconds: 1), (count) => count % 100 + 1);
    _subscription = batteryLevelStream.listen((level) {
      setState(() {
        _batteryLevel = level;
      });
    });
  }

  @override
  void dispose() {
    _subscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Battery Level Stream'),
      ),
      body: Center(
        child: Text('Battery Level: $_batteryLevel%'),
      ),
    );
  }
}

在上述代码中,Stream.periodic 模拟了一个每秒更新一次的电池电量数据流,listen 方法监听这个数据流并在数据更新时通过 setState 更新 UI,这是 Future 无法直接实现的实时更新功能,体现了 Stream 在实时数据处理场景中的优势。