本项目是 Flutter/Dart 异步编程的交互式学习示例,涵盖所有核心异步 API。
API
核心用途
典型场景
Future
单次异步操作
网络请求、文件读写、数据库查询
Stream
多值异步数据流
WebSocket、事件监听、实时数据
async*/yield
按需生成异步序列
分页加载、轮询、批量处理
Isolate
多线程并行计算
图片处理、JSON 解析、加密计算
Timer
定时/延时执行
倒计时、防抖、节流、轮询
Completer
手动控制 Future
封装回调 API、条件等待
FutureBuilder
异步数据驱动 UI
初始化加载、一次性数据获取
StreamBuilder
数据流驱动 UI
实时更新、状态监听
Zone
异步执行上下文
全局错误捕获、日志追踪
Future<T> 表示一个将在未来完成的异步操作,返回类型为 T 的值。
// 基础用法
final result = await someAsyncOperation ();
// Dart 3 并行执行 (推荐)
final (a, b, c) = await (futureA, futureB, futureC).wait;
// 竞速 - 取最快完成的
final fastest = await Future .any ([server1 (), server2 ()]);
// 超时控制
final result = await fetchData ().timeout (Duration (seconds: 5 ));
场景
API
说明
网络请求
async/await
HTTP GET/POST
并行请求
(f1, f2).wait
同时发起多个请求
竞速/容灾
Future.any
多服务器取最快响应
超时控制
.timeout()
防止无限等待
文件读写
async/await
本地 I/O 操作
✅ 使用 Dart 3 Record 语法 (f1, f2).wait 替代 Future.wait([])
✅ 始终处理异常:try-catch 或 .catchError()
❌ 避免在循环中串行 await,应使用并行执行
2. Stream + StreamController
Stream<T> 表示异步数据序列,可以产生多个值。
// 创建 StreamController
final controller = StreamController <int >.broadcast (); // 多订阅
final controller = StreamController <int >(); // 单订阅
// 发送数据
controller.add (value);
controller.addError (error);
controller.close ();
// 监听
final subscription = stream.listen (
(data) => print (data),
onError: (e) => print ('Error: $e ' ),
onDone: () => print ('Done' ),
);
// 操作符
stream.map ((x) => x * 2 )
.where ((x) => x > 10 )
.distinct ()
.take (5 )
场景
API
说明
WebSocket
Stream
实时双向通信
事件总线
StreamController.broadcast
多组件通信
搜索防抖
stream.debounce()
输入框搜索
实时数据
Stream
股票行情、聊天消息
文件流
Stream<List<int>>
大文件分块读取
类型
订阅者数量
数据缓存
典型场景
单订阅
1 个
有
文件读取、HTTP 响应
广播
多个
无
事件总线、状态广播
✅ 在 dispose() 中取消订阅:subscription.cancel()
✅ 关闭 controller:controller.close()
❌ 单订阅 Stream 不能多次 listen
使用 async* 和 yield 创建按需生成值的异步序列。
// 异步生成器
Stream <int > countStream (int max) async * {
for (int i = 1 ; i <= max; i++ ) {
await Future .delayed (Duration (seconds: 1 ));
yield i; // 逐个产出值
}
}
// yield* 委托另一个 Stream
Stream <int > combined () async * {
yield * stream1;
yield * stream2;
}
场景
说明
分页加载
按需加载下一页数据
轮询 API
定时获取最新数据
批量处理
逐条处理大量数据
进度报告
长任务进度更新
语法
作用
yield value
产出单个值
yield* stream
委托整个 Stream
Dart 是单线程模型,Isolate 提供真正的多线程并行能力,每个 Isolate 有独立内存空间。
// 简单用法 - compute()
final result = await compute (heavyTask, inputData);
// 完整用法 - Isolate.spawn
await Isolate .run (() => heavyComputation ());
// 双向通信
final receivePort = ReceivePort ();
await Isolate .spawn (workerFunction, receivePort.sendPort);
场景
推荐 API
说明
JSON 解析
compute()
大型 JSON 数据
图片处理
compute()
压缩、滤镜、裁剪
加密计算
Isolate.run
哈希、加解密
数据分析
Isolate
统计计算
文件压缩
compute()
ZIP 压缩/解压
// ❌ 错误:闭包捕获外部变量
String prefix = 'Result: ' ;
await compute ((data) => prefix + data, input); // 报错!
// ✅ 正确:使用顶层函数 + 参数传递
String processData (Map <String , dynamic > params) {
return params['prefix' ] + params['data' ];
}
await compute (processData, {'prefix' : 'Result: ' , 'data' : input});
✅ 使用顶层函数或静态方法
✅ 通过参数传递所有需要的数据
❌ 不能传递闭包、实例方法
❌ Isolate 间不能共享内存
Timer 用于延时执行或周期性执行任务。
// 延时执行
Timer (Duration (seconds: 2 ), () => doSomething ());
// 周期执行
Timer .periodic (Duration (seconds: 1 ), (timer) {
print ('Tick: ${timer .tick }' );
if (timer.tick >= 10 ) timer.cancel ();
});
// 取消
timer.cancel ();
场景
API
说明
倒计时
Timer.periodic
验证码倒计时
防抖
Timer + cancel
搜索输入延迟
节流
Timer + 标志位
按钮防重复点击
轮询
Timer.periodic
定时刷新数据
延时操作
Timer
延迟显示提示
// 防抖 (Debounce): 停止输入后才执行
Timer ? _debounceTimer;
void onSearchChanged (String query) {
_debounceTimer? .cancel ();
_debounceTimer = Timer (Duration (milliseconds: 500 ), () {
performSearch (query);
});
}
// 节流 (Throttle): 固定间隔内只执行一次
bool _isThrottled = false ;
void onButtonPressed () {
if (_isThrottled) return ;
_isThrottled = true ;
performAction ();
Timer (Duration (seconds: 1 ), () => _isThrottled = false );
}
✅ 在 dispose() 中取消 Timer
✅ 回调中检查 mounted 状态
❌ 不取消 Timer 会导致内存泄漏
Completer<T> 允许手动控制 Future 的完成时机,用于封装回调式 API。
// 创建
final completer = Completer <String >();
// 完成
completer.complete ('success' );
completer.completeError ('error' );
// 获取 Future
final result = await completer.future;
// 检查状态
if (! completer.isCompleted) {
completer.complete (value);
}
场景
说明
封装回调 API
将 callback 转为 Future
条件等待
等待某个条件满足
一次性事件
等待用户确认
资源初始化
等待初始化完成
Future <Position > getCurrentPosition () {
final completer = Completer <Position >();
geolocation.getCurrentPosition (
(position) => completer.complete (position),
(error) => completer.completeError (error),
);
return completer.future;
}
✅ 完成前检查 isCompleted
❌ 重复调用 complete() 会抛异常
❌ 忘记 complete 会导致 Future 永远挂起
7. FutureBuilder / StreamBuilder
Flutter 提供的声明式异步 Widget,自动根据异步状态更新 UI。
FutureBuilder <User >(
future: fetchUser (), // ⚠️ 不要在 build 中创建
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState .waiting) {
return CircularProgressIndicator ();
}
if (snapshot.hasError) {
return Text ('Error: ${snapshot .error }' );
}
return Text ('Hello, ${snapshot .data !.name }' );
},
)
StreamBuilder <int >(
stream: counterStream,
initialData: 0 ,
builder: (context, snapshot) {
return Text ('Count: ${snapshot .data }' );
},
)
Widget
场景
FutureBuilder
初始化加载、一次性数据获取
StreamBuilder
实时数据、状态监听、计数器
// ❌ 错误:在 build 中创建 Future
Widget build (context) {
return FutureBuilder (
future: fetchData (), // 每次 build 都创建新 Future!
...
);
}
// ✅ 正确:在 initState 中创建
late Future <Data > _dataFuture;
@override
void initState () {
super .initState ();
_dataFuture = fetchData ();
}
Widget build (context) {
return FutureBuilder (
future: _dataFuture,
...
);
}
Zone 是异步操作的执行上下文,可以捕获错误、传递上下文数据。
// 全局错误捕获
runZonedGuarded (
() => runApp (MyApp ()),
(error, stack) => reportError (error, stack),
);
// 上下文传递
final zone = Zone .current.fork (
zoneValues: {'requestId' : '12345' },
);
zone.run (() {
print (Zone .current['requestId' ]); // '12345'
});
场景
说明
全局错误捕获
捕获未处理的异步异常
请求追踪
传递 requestId 等上下文
日志增强
自动添加上下文信息
性能监控
追踪异步操作耗时
✅ 用于全局错误上报(如 Sentry、Firebase Crashlytics)
✅ 配合 FlutterError.onError 捕获 Flutter 框架错误
❌ 不要过度使用,会增加复杂度
// ❌ 错误
void saveData () {
database.save (data); // 没有 await,不会等待完成
showSuccess (); // 可能在保存完成前执行
}
// ✅ 正确
Future <void > saveData () async {
await database.save (data);
showSuccess ();
}
// ❌ 慢:串行执行
for (final url in urls) {
await fetch (url); // 一个一个等待
}
// ✅ 快:并行执行
await Future .wait (urls.map ((url) => fetch (url)));
// ❌ 错误:异常未捕获
final data = await fetchData ();
// ✅ 正确
try {
final data = await fetchData ();
} catch (e) {
handleError (e);
}
// ❌ 错误:未取消订阅
StreamSubscription ? _subscription;
void initState () {
_subscription = stream.listen (...);
}
// 忘记在 dispose 中取消
// ✅ 正确
void dispose () {
_subscription? .cancel ();
_timer? .cancel ();
_controller? .close ();
super .dispose ();
}
错误 5:setState 在 dispose 后调用
// ❌ 错误
Timer (Duration (seconds: 2 ), () {
setState (() { ... }); // Widget 可能已销毁
});
// ✅ 正确
Timer (Duration (seconds: 2 ), () {
if (! mounted) return ;
setState (() { ... });
});
// ❌ 错误:闭包捕获外部变量
String prefix = 'Hello' ;
await compute ((msg) => prefix + msg, 'World' );
// ✅ 正确:参数传递
await compute (greet, {'prefix' : 'Hello' , 'msg' : 'World' });
String greet (Map <String , String > params) {
return params['prefix' ]! + params['msg' ]! ;
}
lib/
├── main.dart # 入口 + 首页
├── examples/ # 纯 Dart 示例代码
│ ├── 01_future_async_await.dart
│ ├── 02_stream_controller.dart
│ └── ...
└── pages/ # Flutter 交互式演示
├── future/
│ ├── future_demo_page.dart
│ └── future_readme.md
├── stream/
├── generator/
├── isolate/
├── timer/
├── completer/
├── builder/
├── zone/
└── mistakes/
flutter pub get
flutter run
本项目使用 Dart 3 语法,推荐 Flutter 3.10+ 版本运行。