Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flutter 异步编程完整指南

本项目是 Flutter/Dart 异步编程的交互式学习示例,涵盖所有核心异步 API。

目录


API 速查表

API 核心用途 典型场景
Future 单次异步操作 网络请求、文件读写、数据库查询
Stream 多值异步数据流 WebSocket、事件监听、实时数据
async*/yield 按需生成异步序列 分页加载、轮询、批量处理
Isolate 多线程并行计算 图片处理、JSON 解析、加密计算
Timer 定时/延时执行 倒计时、防抖、节流、轮询
Completer 手动控制 Future 封装回调 API、条件等待
FutureBuilder 异步数据驱动 UI 初始化加载、一次性数据获取
StreamBuilder 数据流驱动 UI 实时更新、状态监听
Zone 异步执行上下文 全局错误捕获、日志追踪

1. Future + async/await

概念

Future<T> 表示一个将在未来完成的异步操作,返回类型为 T 的值。

核心 API

// 基础用法
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> 表示异步数据序列,可以产生多个值。

核心 API

// 创建 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>> 大文件分块读取

单订阅 vs 广播

类型 订阅者数量 数据缓存 典型场景
单订阅 1 个 文件读取、HTTP 响应
广播 多个 事件总线、状态广播

注意事项

  • ✅ 在 dispose() 中取消订阅:subscription.cancel()
  • ✅ 关闭 controller:controller.close()
  • ❌ 单订阅 Stream 不能多次 listen

3. async*/yield 生成器

概念

使用 async*yield 创建按需生成值的异步序列。

核心 API

// 异步生成器
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 vs yield*

语法 作用
yield value 产出单个值
yield* stream 委托整个 Stream

4. Isolate + compute()

概念

Dart 是单线程模型,Isolate 提供真正的多线程并行能力,每个 Isolate 有独立内存空间。

核心 API

// 简单用法 - 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 间不能共享内存

5. Timer 定时器

概念

Timer 用于延时执行或周期性执行任务。

核心 API

// 延时执行
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 延迟显示提示

防抖 vs 节流

// 防抖 (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 会导致内存泄漏

6. Completer

概念

Completer<T> 允许手动控制 Future 的完成时机,用于封装回调式 API。

核心 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

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

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,
    ...
  );
}

8. Zone 高级用法

概念

Zone 是异步操作的执行上下文,可以捕获错误、传递上下文数据。

核心 API

// 全局错误捕获
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 框架错误
  • ❌ 不要过度使用,会增加复杂度

9. 常见错误与最佳实践

错误 1:忘记 await

// ❌ 错误
void saveData() {
  database.save(data);  // 没有 await,不会等待完成
  showSuccess();        // 可能在保存完成前执行
}

// ✅ 正确
Future<void> saveData() async {
  await database.save(data);
  showSuccess();
}

错误 2:循环中串行 await

// ❌ 慢:串行执行
for (final url in urls) {
  await fetch(url);  // 一个一个等待
}

// ✅ 快:并行执行
await Future.wait(urls.map((url) => fetch(url)));

错误 3:未处理异常

// ❌ 错误:异常未捕获
final data = await fetchData();

// ✅ 正确
try {
  final data = await fetchData();
} catch (e) {
  handleError(e);
}

错误 4:资源泄漏

// ❌ 错误:未取消订阅
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(() { ... });
});

错误 6:Isolate 共享内存

// ❌ 错误:闭包捕获外部变量
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+ 版本运行。

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages