文章目录
-
- 摘要
- 前言
- 一、异步编程概述
-
- [1.1 同步与异步](#1.1 同步与异步)
- [1.2 Dart事件循环](#1.2 Dart事件循环)
- [1.3 为什么要异步](#1.3 为什么要异步)
- 二、Future详解
-
- [2.1 创建Future](#2.1 创建Future)
- [2.2 then回调](#2.2 then回调)
- [2.3 Future辅助方法](#2.3 Future辅助方法)
- [2.4 Future超时](#2.4 Future超时)
- 三、async与await
-
- [3.1 async函数](#3.1 async函数)
- [3.2 await表达式](#3.2 await表达式)
- [3.3 await for循环](#3.3 await for循环)
- 四、错误处理
-
- [4.1 try-catch-finally](#4.1 try-catch-finally)
- 总结
摘要
异步编程是Dart的核心特性,Future和async-await是处理异步操作的基础。Flutter应用中大量使用异步代码,理解异步编程至关重要。这篇文章我想深入讲解Dart的Future和async-await机制。
前言
一开始写Flutter代码的时候,异步编程让我很困惑。Future、async、await...这些概念怎么用?
后来慢慢理解了,异步就是"不等待",让代码在等待的时候能去做别的事。这篇文章我想分享异步编程的学习和实践经验。
一、异步编程概述
1.1 同步与异步
dart
// 同步代码:按顺序执行
void syncExample() {
print('开始');
var result = compute();
print('结果:$result');
print('结束');
}
String compute() {
// 模拟耗时操作
return '计算完成';
}
// 输出:
// 开始
// 结果:计算完成
// 结束
// 异步代码:不等待
void asyncExample() {
print('开始');
asyncCompute();
print('结束');
}
Future<void> asyncCompute() async {
await Future.delayed(Duration(seconds: 1));
print('计算完成');
}
// 输出:
// 开始
// 结束
// (1秒后)
// 计算完成
1.2 Dart事件循环
dart
// Dart是单线程的,使用事件循环处理异步
void eventLoopDemo() {
print('1. 同步代码');
// 微任务队列
scheduleMicrotask(() {
print('4. 微任务');
});
// 事件队列
Future(() {
print('6. 事件队列1');
scheduleMicrotask(() {
print('7. 事件队列中的微任务');
});
});
Future(() {
print('8. 事件队列2');
});
print('2. 同步代码');
print('3. 同步代码');
}
// 执行顺序:
// 1. 同步代码
// 2. 同步代码
// 3. 同步代码
// 4. 微任务
// 6. 事件队列1
// 7. 事件队列中的微任务
// 8. 事件队列2
1.3 为什么要异步
dart
// 网络请求示例(同步会导致卡顿)
void syncFetch() {
// 假设这个请求需要3秒
var data = fetchData(); // UI会冻结3秒
updateUI(data);
}
// 异步请求:不阻塞UI
void asyncFetch() async {
showLoading();
var data = await fetchData(); // UI保持响应
hideLoading();
updateUI(data);
}
大家都不喜欢设备卡住得感觉吧
二、Future详解
2.1 创建Future
dart
// Future.value:创建一个有值的Future
Future<int> getValue() {
return Future.value(42);
}
// Future.delayed:延迟执行
Future<String> delayedValue() {
return Future.delayed(
Duration(seconds: 2),
() => '延迟2秒的值',
);
}
// Future.error:创建一个错误的Future
Future<void> getError() {
return Future.error(Exception('出错了'));
}
// Future构造函数
Future<int> compute() {
return Future(() {
var sum = 0;
for (var i = 0; i < 1000000; i++) {
sum += i;
}
return sum;
});
}

2.2 then回调
dart
void thenDemo() {
Future(() {
return '异步结果';
}).then((value) {
print('收到:$value');
return '处理后的$value';
}).then((value) {
print('再次处理:$value');
}).catchError((error) {
print('错误:$error');
}).whenComplete(() {
print('完成');
});
}
// 链式调用
Future<int> parseAndAdd(String str) {
return Future.value(str)
.then((s) => int.parse(s))
.then((n) => n + 10)
.catchError((e) => 0);
}
2.3 Future辅助方法
dart
void futureHelpers() {
// Future.wait:等待多个Future完成
Future.wait([
Future.delayed(Duration(seconds: 1), () => 'A'),
Future.delayed(Duration(seconds: 2), () => 'B'),
Future.delayed(Duration(seconds: 3), () => 'C'),
]).then((values) {
print('全部完成:$values'); // [A, B, C]
});
// Future.any:任意一个完成就返回
Future.any([
Future.delayed(Duration(seconds: 3), () => '慢'),
Future.delayed(Duration(seconds: 1), () => '快'),
]).then((value) {
print(value); // 快
});
// Future.doWhile:循环直到条件不满足
var count = 0;
Future.doWhile(() async {
await Future.delayed(Duration(seconds: 1));
count++;
print('计数:$count');
return count < 3;
});
// Future.forEach:遍历异步操作
Future.forEach([1, 2, 3], (n) async {
await Future.delayed(Duration(milliseconds: 500));
print('处理:$n');
});
}
2.4 Future超时
dart
Future<String> fetchWithTimeout() {
return Future.delayed(Duration(seconds: 5), () => '数据')
.timeout(
Duration(seconds: 2),
onTimeout: () {
return '超时返回默认值';
},
);
}
// 或者抛出超时异常
Future<String> fetchWithTimeout2() {
return Future.delayed(Duration(seconds: 5), () => '数据')
.timeout(
Duration(seconds: 2),
onTimeout: () => throw TimeoutException('请求超时'),
);
}
三、async与await
3.1 async函数
dart
// 声明async函数
Future<String> fetchUser() async {
await Future.delayed(Duration(seconds: 1));
return '张三';
}
// async函数自动返回Future
String getUserName() async { // 返回Future<String>
await Future.delayed(Duration(seconds: 1));
return '李四';
}
// void可以变成Future<void>
void printMessage() async { // 返回Future<void>
await Future.delayed(Duration(seconds: 1));
print('消息');
}
3.2 await表达式
dart
Future<void> awaitDemo() async {
// await会暂停函数执行,等待Future完成
print('开始');
var result1 = await Future.delayed(
Duration(seconds: 1),
() => '第一个结果',
);
print(result1);
var result2 = await Future.delayed(
Duration(seconds: 1),
() => '第二个结果',
);
print(result2);
print('结束');
}
//输出
开始
(等待1秒)
第一个结果
(等待1秒)
第二个结果
结束
// 顺序执行vs并行执行
Future<void> sequential() async {
var a = await taskA(); // 3秒
var b = await taskB(); // 2秒
var c = await taskC(); // 1秒
// 总共6秒
}
Future<void> parallel() async {
var results = await Future.wait([
taskA(), // 3秒
taskB(), // 2秒
taskC(), // 1秒
]);
// 总共3秒
}
3.3 await for循环
dart
// await for处理Stream
Future<void> streamConsumer() async {
var stream = Stream.periodic(
Duration(seconds: 1),
(count) => count,
).take(5);
// await for会等待每个事件
await for (var value in stream) {
print('收到:$value');
}
print('流结束');
}
四、错误处理
4.1 try-catch-finally
dart
Future<void> errorHandling() async {
try {
var data = await mayThrowError();
print(data);
} on FormatException catch (e) {
print('格式错误:$e');
} on NetworkException catch (e) {
print('网络错误:$e');
} catch (e, stackTrace) {
print('未知错误:$e');
print('堆栈:$stackTrace');
} finally {
print('无论如何都执行');
}
}
Future<String> mayThrowError() async {
await Future.delayed(Duration(seconds: 1));
throw FormatException('格式错误');
}
总结
异步编程是Dart的核心,掌握Future和async-await至关重要。
核心要点:
- 异步让代码不阻塞,保持UI响应
- Future表示异步操作的最终结果
- async/await让异步代码像同步代码
- 错误处理使用try-catch
- 合理使用Future.wait并行执行
最佳实践:
- 优先使用async/await而非then
- 独立任务并行执行
- 依赖任务顺序执行
- 做好错误处理和超时控制
- 避免回调地狱
异步编程是Flutter开发的基础,需要深入理解。
欢迎加入开源鸿蒙跨平台社区:开源鸿蒙跨平台开发者社区