面试题答案
一键面试Future 和 Stream 在异步数据加载场景下的特点对比
- Future:
- 特点:
- 表示一个异步操作的最终结果,只能返回单个值。一旦 Future 完成(无论是成功还是失败),它就不会再产生新的值。
- 适用于那些只需要获取一次异步操作结果的场景,例如网络请求获取单个数据对象、读取本地文件等。
- 适用场景:数据获取操作只执行一次,并且期望在操作完成后立即得到结果。比如登录接口调用,只需要获取登录是否成功这一个结果。
- 特点:
- 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 在实时数据处理场景中的优势。