Dart Future 全面指南
目录
- Future 基础概念
- Future 的创建
- Future 的处理方式
- 错误处理
- Future 组合与链式调用
- async/await 语法
- 高级用法
- 性能优化与最佳实践
- 实际应用示例
- 常见问题与解决方案
Future 基础概念
什么是 Future?
Future 是 Dart 中用于表示异步操作的核心类,它代表一个可能在未来某个时间点完成的计算或操作。Future 可以:
- 表示一个异步操作的结果
- 在操作完成时提供结果值
- 在操作失败时提供错误信息
Future 的状态
Future 有三种状态:
- 未完成(Uncompleted): 异步操作正在进行中
- 已完成且有值(Completed with a value): 操作成功完成并返回结果
- 已完成且有错误(Completed with an error): 操作失败并抛出异常
// Future 状态示例
Future<String> pendingFuture = Future.delayed(Duration(seconds: 2), () => "完成");
Future<String> completedFuture = Future.value("立即完成");
Future<String> errorFuture = Future.error("发生错误");
Future 的类型
// 泛型 Future,指定返回值类型
Future<int> intFuture = Future.value(42);
Future<String> stringFuture = Future.value("Hello");
Future<List<String>> listFuture = Future.value(["a", "b", "c"]);
// 无返回值的 Future
Future<void> voidFuture = Future(() => print("操作完成"));
Future 的创建
1. 使用构造函数
// 基本构造函数
Future<String> future1 = Future(() {
// 执行异步操作
return "操作结果";
});
// 立即返回值
Future<String> future2 = Future.value("立即完成");
// 立即返回错误
Future<String> future3 = Future.error("错误信息");
2. 使用 Future.delayed
// 延迟执行
Future<String> delayedFuture = Future.delayed(
Duration(seconds: 2),
() => "2秒后完成"
);
// 延迟执行无返回值
Future<void> delayedVoidFuture = Future.delayed(
Duration(milliseconds: 500),
() => print("500ms后执行")
);
3. 使用 Future.microtask
// 在微任务队列中执行
Future<String> microtaskFuture = Future.microtask(() {
print("在微任务队列中执行");
return "微任务结果";
});
4. 使用 Future.sync
// 同步执行,但返回 Future
Future<String> syncFuture = Future.sync(() {
// 如果这里抛出异常,会被包装成 Future.error
return "同步执行的结果";
});
5. 使用 Completer
import 'dart:async';
// 手动控制 Future 的完成
Completer<String> completer = Completer<String>();
Future<String> future = completer.future;
// 在某个时刻完成 Future
Timer(Duration(seconds: 1), () {
completer.complete("手动完成");
});
// 或者完成时带有错误
// completer.completeError("发生错误");
Future 的处理方式
1. 使用 then() 方法
Future<String> fetchData() {
return Future.delayed(Duration(seconds: 1), () => "数据");
}
void handleFuture() {
fetchData().then((data) {
print("获取到数据: $data");
});
}
// 链式调用
fetchData()
.then((data) => data.toUpperCase())
.then((upperData) => print("转换后: $upperData"));
2. 类型转换
Future<String> stringFuture = Future.value("42");
// 转换为其他类型
Future<int> intFuture = stringFuture.then((str) => int.parse(str));
// 链式转换
Future<String> result = Future.value("hello")
.then((str) => str.length)
.then((length) => "长度是: $length");
3. 处理多个 Future 的结果
Future<String> future1 = Future.delayed(Duration(seconds: 1), () => "第一个");
Future<String> future2 = Future.delayed(Duration(seconds: 2), () => "第二个");
future1.then((result1) {
return future2.then((result2) {
return "$result1 和 $result2";
});
}).then((combinedResult) {
print(combinedResult); // "第一个 和 第二个"
});
错误处理
1. 使用 catchError
Future<String> riskyOperation() {
return Future.delayed(Duration(seconds: 1), () {
if (DateTime.now().millisecondsSinceEpoch % 2 == 0) {
throw Exception("随机错误");
}
return "成功";
});
}
void handleErrors() {
riskyOperation()
.then((result) => print("成功: $result"))
.catchError((error) => print("错误: $error"));
}
2. 指定错误类型处理
class NetworkError extends Error {}
class ValidationError extends Error {}
Future<String> complexOperation() {
// 可能抛出不同类型的错误
return Future.error(NetworkError());
}
void handleSpecificErrors() {
complexOperation()
.catchError((error) {
print("网络错误: $error");
return "网络错误的默认值";
}, test: (error) => error is NetworkError)
.catchError((error) {
print("验证错误: $error");
return "验证错误的默认值";
}, test: (error) => error is ValidationError)
.catchError((error) {
print("其他错误: $error");
return "通用默认值";
});
}
3. 使用 whenComplete
Future<String> operationWithCleanup() {
return Future.delayed(Duration(seconds: 1), () => "完成")
.whenComplete(() {
print("无论成功还是失败都会执行清理操作");
});
}
4. 错误恢复
Future<String> fetchWithFallback() {
return fetchData()
.catchError((error) {
print("主要数据源失败: $error");
return fetchBackupData(); // 返回备用数据源的 Future
});
}
Future<String> fetchBackupData() {
return Future.delayed(Duration(seconds: 1), () => "备用数据");
}
Future 组合与链式调用
1. Future.wait - 等待所有 Future 完成
Future<void> waitForAll() async {
List<Future<String>> futures = [
Future.delayed(Duration(seconds: 1), () => "任务1"),
Future.delayed(Duration(seconds: 2), () => "任务2"),
Future.delayed(Duration(seconds: 3), () => "任务3"),
];
try {
List<String> results = await Future.wait(futures);
print("所有任务完成: $results");
} catch (error) {
print("有任务失败: $error");
}
}
2. Future.wait 的选项
Future<void> waitWithOptions() async {
List<Future<String>> futures = [
Future.delayed(Duration(seconds: 1), () => "任务1"),
Future.delayed(Duration(seconds: 2), () => throw "任务2失败"),
Future.delayed(Duration(seconds: 3), () => "任务3"),
];
// eagerError: false 表示等待所有任务完成,即使有错误
try {
List<String> results = await Future.wait(futures, eagerError: false);
print("结果: $results"); // 可能包含错误
} catch (error) {
print("错误: $error");
}
}
3. 自定义组合操作
Future<Map<String, dynamic>> combineUserData(String userId) async {
// 并行获取用户的不同信息
Future<String> nameFuture = fetchUserName(userId);
Future<int> ageFuture = fetchUserAge(userId);
Future<List<String>> hobbyFuture = fetchUserHobbies(userId);
// 等待所有数据
List<dynamic> results = await Future.wait([
nameFuture,
ageFuture,
hobbyFuture,
]);
return {
'name': results[0] as String,
'age': results[1] as int,
'hobbies': results[2] as List<String>,
};
}
Future<String> fetchUserName(String userId) =>
Future.delayed(Duration(seconds: 1), () => "张三");
Future<int> fetchUserAge(String userId) =>
Future.delayed(Duration(seconds: 1), () => 25);
Future<List<String>> fetchUserHobbies(String userId) =>
Future.delayed(Duration(seconds: 1), () => ["阅读", "游泳"]);
4. Future.any - 等待任何一个完成
Future<String> raceCondition() {
List<Future<String>> futures = [
Future.delayed(Duration(seconds: 3), () => "慢速服务器"),
Future.delayed(Duration(seconds: 1), () => "快速服务器"),
Future.delayed(Duration(seconds: 2), () => "中速服务器"),
];
return Future.any(futures); // 返回最先完成的结果
}
async/await 语法
1. 基本用法
// 异步函数必须标记为 async
Future<String> fetchUserData() async {
// 使用 await 等待异步操作完成
String userData = await Future.delayed(
Duration(seconds: 2),
() => "用户数据"
);
return userData;
}
// 调用异步函数
void main() async {
print("开始获取数据");
String data = await fetchUserData();
print("获取到数据: $data");
}
2. 错误处理
Future<String> riskyAsyncOperation() async {
try {
String result = await Future.delayed(
Duration(seconds: 1),
() => throw Exception("操作失败")
);
return result;
} catch (error) {
print("捕获错误: $error");
return "默认值";
} finally {
print("清理操作");
}
}
3. 顺序执行多个异步操作
Future<String> sequentialOperations() async {
print("开始第一个操作");
String result1 = await Future.delayed(
Duration(seconds: 1),
() => "第一个结果"
);
print("开始第二个操作");
String result2 = await Future.delayed(
Duration(seconds: 1),
() => "第二个结果"
);
return "$result1 + $result2";
}
4. 并行执行多个异步操作
Future<String> parallelOperations() async {
// 同时启动多个异步操作
Future<String> future1 = Future.delayed(
Duration(seconds: 2),
() => "并行任务1"
);
Future<String> future2 = Future.delayed(
Duration(seconds: 3),
() => "并行任务2"
);
// 等待所有操作完成
List<String> results = await Future.wait([future1, future2]);
return results.join(" + ");
}
5. 条件异步操作
Future<String> conditionalAsync(bool condition) async {
if (condition) {
String result = await expensiveOperation();
return "条件满足: $result";
} else {
return "条件不满足";
}
}
Future<String> expensiveOperation() async {
return await Future.delayed(Duration(seconds: 2), () => "昂贵操作结果");
}
高级用法
1. Future 流水线处理
Future<String> processPipeline(String input) {
return Future.value(input)
.then((data) => validateInput(data))
.then((validData) => transformData(validData))
.then((transformedData) => saveData(transformedData))
.then((savedData) => generateReport(savedData));
}
Future<String> validateInput(String input) async {
if (input.isEmpty) throw ArgumentError("输入不能为空");
return input;
}
Future<String> transformData(String data) async {
return data.toUpperCase();
}
Future<String> saveData(String data) async {
// 模拟保存操作
await Future.delayed(Duration(milliseconds: 500));
return "已保存: $data";
}
Future<String> generateReport(String data) async {
return "报告: $data";
}
2. 超时处理
Future<String> operationWithTimeout() {
return Future.delayed(Duration(seconds: 5), () => "长时间操作")
.timeout(Duration(seconds: 3), onTimeout: () {
throw TimeoutException("操作超时", Duration(seconds: 3));
});
}
// 使用示例
void handleTimeout() async {
try {
String result = await operationWithTimeout();
print("结果: $result");
} on TimeoutException catch (e) {
print("超时错误: ${e.message}");
}
}
3. 重试机制
Future<String> retryOperation({int maxRetries = 3}) async {
int attempt = 0;
while (attempt < maxRetries) {
try {
attempt++;
print("尝试第 $attempt 次");
// 模拟可能失败的操作
if (attempt < 3) {
throw Exception("操作失败");
}
return "操作成功";
} catch (error) {
if (attempt >= maxRetries) {
throw Exception("重试 $maxRetries 次后仍然失败: $error");
}
// 等待一段时间再重试
await Future.delayed(Duration(seconds: attempt));
}
}
throw Exception("不应该到达这里");
}
4. 缓存机制
class DataCache {
final Map<String, Future<String>> _cache = {};
Future<String> getData(String key) {
// 如果缓存中已有正在进行的请求,直接返回
if (_cache.containsKey(key)) {
return _cache[key]!;
}
// 创建新的请求并缓存
Future<String> future = _fetchData(key);
_cache[key] = future;
// 请求完成后清理缓存
future.whenComplete(() => _cache.remove(key));
return future;
}
Future<String> _fetchData(String key) async {
// 模拟网络请求
await Future.delayed(Duration(seconds: 2));
return "数据-$key";
}
}
5. Future 转换工具
extension FutureExtensions<T> on Future<T> {
// 添加日志
Future<T> withLogging(String operation) {
return this
.then((result) {
print("$operation 成功: $result");
return result;
})
.catchError((error) {
print("$operation 失败: $error");
throw error;
});
}
// 添加默认值
Future<T> withDefault(T defaultValue) {
return this.catchError((_) => defaultValue);
}
// 添加延迟
Future<T> withDelay(Duration delay) {
return this.then((result) async {
await Future.delayed(delay);
return result;
});
}
}
// 使用示例
void useExtensions() async {
String result = await Future.delayed(Duration(seconds: 1), () => "结果")
.withLogging("数据获取")
.withDefault("默认值")
.withDelay(Duration(milliseconds: 500));
print("最终结果: $result");
}
性能优化与最佳实践
1. 避免不必要的 await
// ❌ 不好的做法 - 不必要的 await
Future<String> badExample() async {
String result = await processData();
return result; // 直接返回 Future 即可
}
// ✅ 好的做法
Future<String> goodExample() {
return processData(); // 直接返回 Future
}
Future<String> processData() async {
return await Future.delayed(Duration(seconds: 1), () => "数据");
}
2. 合理使用并行处理
// ❌ 串行处理(慢)
Future<List<String>> serialProcessing() async {
List<String> results = [];
results.add(await fetchData("1"));
results.add(await fetchData("2"));
results.add(await fetchData("3"));
return results;
}
// ✅ 并行处理(快)
Future<List<String>> parallelProcessing() async {
List<Future<String>> futures = [
fetchData("1"),
fetchData("2"),
fetchData("3"),
];
return await Future.wait(futures);
}
Future<String> fetchData(String id) async {
return await Future.delayed(Duration(seconds: 1), () => "数据-$id");
}
3. 资源管理
class ResourceManager {
bool _isDisposed = false;
Future<String> performOperation() async {
if (_isDisposed) {
throw StateError("资源已释放");
}
try {
return await _doWork();
} finally {
// 确保资源被正确清理
await _cleanup();
}
}
Future<String> _doWork() async {
return await Future.delayed(Duration(seconds: 1), () => "工作完成");
}
Future<void> _cleanup() async {
print("清理资源");
}
void dispose() {
_isDisposed = true;
}
}
4. 错误边界
class ErrorBoundary {
static Future<T> safeExecute<T>(
Future<T> Function() operation, {
T? fallbackValue,
void Function(Object error)? onError,
}) async {
try {
return await operation();
} catch (error) {
onError?.call(error);
if (fallbackValue != null) {
return fallbackValue;
}
rethrow;
}
}
}
// 使用示例
void useSafeExecute() async {
String result = await ErrorBoundary.safeExecute(
() => riskyOperation(),
fallbackValue: "安全的默认值",
onError: (error) => print("记录错误: $error"),
);
print("结果: $result");
}
Future<String> riskyOperation() async {
if (DateTime.now().millisecondsSinceEpoch % 2 == 0) {
throw Exception("随机错误");
}
return "成功结果";
}
实际应用示例
1. HTTP 请求封装
import 'dart:convert';
import 'dart:io';
class HttpClient {
static const Duration _defaultTimeout = Duration(seconds: 10);
static Future<Map<String, dynamic>> get(String url, {
Map<String, String>? headers,
Duration? timeout,
}) async {
try {
final client = HttpClient();
final request = await client.getUrl(Uri.parse(url));
// 设置请求头
headers?.forEach((key, value) {
request.headers.set(key, value);
});
final response = await request.close()
.timeout(timeout ?? _defaultTimeout);
if (response.statusCode == 200) {
final responseBody = await response.transform(utf8.decoder).join();
return json.decode(responseBody) as Map<String, dynamic>;
} else {
throw HttpException('请求失败: ${response.statusCode}');
}
} catch (error) {
throw Exception('网络请求错误: $error');
}
}
static Future<Map<String, dynamic>> post(
String url,
Map<String, dynamic> data, {
Map<String, String>? headers,
Duration? timeout,
}) async {
try {
final client = HttpClient();
final request = await client.postUrl(Uri.parse(url));
// 设置内容类型
request.headers.contentType = ContentType.json;
// 设置其他请求头
headers?.forEach((key, value) {
request.headers.set(key, value);
});
// 写入请求体
request.write(json.encode(data));
final response = await request.close()
.timeout(timeout ?? _defaultTimeout);
final responseBody = await response.transform(utf8.decoder).join();
if (response.statusCode >= 200 && response.statusCode < 300) {
return json.decode(responseBody) as Map<String, dynamic>;
} else {
throw HttpException('请求失败: ${response.statusCode}');
}
} catch (error) {
throw Exception('网络请求错误: $error');
}
}
}
// 使用示例
void httpExample() async {
try {
// GET 请求
Map<String, dynamic> userData = await HttpClient.get(
'https://api.example.com/users/1',
headers: {'Authorization': 'Bearer token'},
);
print('用户数据: $userData');
// POST 请求
Map<String, dynamic> createResult = await HttpClient.post(
'https://api.example.com/users',
{'name': '张三', 'email': 'zhangsan@example.com'},
);
print('创建结果: $createResult');
} catch (error) {
print('请求失败: $error');
}
}
2. 文件操作
import 'dart:io';
class FileManager {
static Future<String> readTextFile(String path) async {
try {
final file = File(path);
if (!await file.exists()) {
throw FileSystemException('文件不存在', path);
}
return await file.readAsString();
} catch (error) {
throw Exception('读取文件失败: $error');
}
}
static Future<void> writeTextFile(String path, String content) async {
try {
final file = File(path);
// 确保目录存在
await file.parent.create(recursive: true);
await file.writeAsString(content);
} catch (error) {
throw Exception('写入文件失败: $error');
}
}
static Future<List<String>> listDirectory(String path) async {
try {
final directory = Directory(path);
if (!await directory.exists()) {
throw FileSystemException('目录不存在', path);
}
return await directory
.list()
.map((entity) => entity.path)
.toList();
} catch (error) {
throw Exception('列出目录失败: $error');
}
}
static Future<void> copyFile(String sourcePath, String targetPath) async {
try {
final sourceFile = File(sourcePath);
final targetFile = File(targetPath);
if (!await sourceFile.exists()) {
throw FileSystemException('源文件不存在', sourcePath);
}
// 确保目标目录存在
await targetFile.parent.create(recursive: true);
await sourceFile.copy(targetPath);
} catch (error) {
throw Exception('复制文件失败: $error');
}
}
}
// 使用示例
void fileExample() async {
try {
// 写入文件
await FileManager.writeTextFile('test.txt', '这是测试内容');
print('文件写入成功');
// 读取文件
String content = await FileManager.readTextFile('test.txt');
print('文件内容: $content');
// 列出目录
List<String> files = await FileManager.listDirectory('.');
print('目录文件: $files');
// 复制文件
await FileManager.copyFile('test.txt', 'backup/test_backup.txt');
print('文件复制成功');
} catch (error) {
print('文件操作失败: $error');
}
}
3. 数据库操作模拟
class User {
final int id;
final String name;
final String email;
final DateTime createdAt;
User({
required this.id,
required this.name,
required this.email,
required this.createdAt,
});
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'email': email,
'createdAt': createdAt.toIso8601String(),
};
static User fromJson(Map<String, dynamic> json) => User(
id: json['id'],
name: json['name'],
email: json['email'],
createdAt: DateTime.parse(json['createdAt']),
);
}
class UserRepository {
// 模拟数据库
static final List<User> _users = [];
static int _nextId = 1;
static Future<User> create(String name, String email) async {
// 模拟数据库写入延迟
await Future.delayed(Duration(milliseconds: 100));
// 验证邮箱唯一性
if (_users.any((user) => user.email == email)) {
throw Exception('邮箱已存在');
}
final user = User(
id: _nextId++,
name: name,
email: email,
createdAt: DateTime.now(),
);
_users.add(user);
return user;
}
static Future<User?> findById(int id) async {
await Future.delayed(Duration(milliseconds: 50));
try {
return _users.firstWhere((user) => user.id == id);
} catch (e) {
return null;
}
}
static Future<List<User>> findAll() async {
await Future.delayed(Duration(milliseconds: 50));
return List.from(_users);
}
static Future<User?> findByEmail(String email) async {
await Future.delayed(Duration(milliseconds: 50));
try {
return _users.firstWhere((user) => user.email == email);
} catch (e) {
return null;
}
}
static Future<bool> update(int id, {String? name, String? email}) async {
await Future.delayed(Duration(milliseconds: 100));
final userIndex = _users.indexWhere((user) => user.id == id);
if (userIndex == -1) return false;
// 如果更新邮箱,检查唯一性
if (email != null && email != _users[userIndex].email) {
if (_users.any((user) => user.email == email)) {
throw Exception('邮箱已存在');
}
}
final oldUser = _users[userIndex];
_users[userIndex] = User(
id: oldUser.id,
name: name ?? oldUser.name,
email: email ?? oldUser.email,
createdAt: oldUser.createdAt,
);
return true;
}
static Future<bool> delete(int id) async {
await Future.delayed(Duration(milliseconds: 100));
final userIndex = _users.indexWhere((user) => user.id == id);
if (userIndex == -1) return false;
_users.removeAt(userIndex);
return true;
}
}
// 使用示例
void databaseExample() async {
try {
// 创建用户
User user1 = await UserRepository.create('张三', 'zhangsan@example.com');
print('创建用户: ${user1.name} (${user1.id})');
User user2 = await UserRepository.create('李四', 'lisi@example.com');
print('创建用户: ${user2.name} (${user2.id})');
// 查询所有用户
List<User> allUsers = await UserRepository.findAll();
print('所有用户: ${allUsers.map((u) => u.name).join(', ')}');
// 根据ID查询
User? foundUser = await UserRepository.findById(1);
if (foundUser != null) {
print('找到用户: ${foundUser.name}');
}
// 更新用户
bool updated = await UserRepository.update(1, name: '张三丰');
if (updated) {
print('用户更新成功');
}
// 根据邮箱查询
User? userByEmail = await UserRepository.findByEmail('zhangsan@example.com');
if (userByEmail != null) {
print('通过邮箱找到用户: ${userByEmail.name}');
}
// 删除用户
bool deleted = await UserRepository.delete(2);
if (deleted) {
print('用户删除成功');
}
} catch (error) {
print('数据库操作失败: $error');
}
}
常见问题与解决方案
1. Future 未被等待的警告
// ❌ 问题:Future 未被正确处理
void problematicFunction() {
fetchData(); // 警告:未等待的 Future
}
// ✅ 解决方案1:使用 await
Future<void> solution1() async {
await fetchData();
}
// ✅ 解决方案2:使用 unawaited(如果确实不需要等待)
import 'dart:async';
void solution2() {
unawaited(fetchData()); // 明确表示不等待
}
// ✅ 解决方案3:处理 Future
void solution3() {
fetchData().then((result) {
print('结果: $result');
}).catchError((error) {
print('错误: $error');
});
}
Future<String> fetchData() async {
return await Future.delayed(Duration(seconds: 1), () => "数据");
}
2. 内存泄漏问题
class ProblematicClass {
Timer? _timer;
StreamSubscription? _subscription;
// ❌ 问题:没有正确清理资源
void startPeriodicTask() {
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
performTask();
});
}
Future<void> performTask() async {
// 执行任务
}
}
// ✅ 解决方案:正确的资源管理
class ProperClass {
Timer? _timer;
StreamSubscription? _subscription;
bool _isDisposed = false;
void startPeriodicTask() {
if (_isDisposed) return;
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
if (_isDisposed) {
timer.cancel();
return;
}
performTask();
});
}
Future<void> performTask() async {
if (_isDisposed) return;
// 执行任务
}
void dispose() {
_isDisposed = true;
_timer?.cancel();
_subscription?.cancel();
}
}
3. 异步操作中的状态管理
class DataManager {
String? _cachedData;
Future<String>? _loadingFuture;
// ❌ 问题:可能导致多次加载
Future<String> getData() async {
if (_cachedData != null) {
return _cachedData!;
}
return await _loadData(); // 每次调用都会重新加载
}
Future<String> _loadData() async {
return await Future.delayed(Duration(seconds: 2), () => "数据");
}
}
// ✅ 解决方案:正确的状态管理
class ImprovedDataManager {
String? _cachedData;
Future<String>? _loadingFuture;
Future<String> getData() async {
// 如果有缓存,直接返回
if (_cachedData != null) {
return _cachedData!;
}
// 如果正在加载,返回正在进行的 Future
if (_loadingFuture != null) {
return await _loadingFuture!;
}
// 开始新的加载
_loadingFuture = _loadData();
try {
_cachedData = await _loadingFuture!;
return _cachedData!;
} finally {
_loadingFuture = null;
}
}
Future<String> _loadData() async {
return await Future.delayed(Duration(seconds: 2), () => "数据");
}
void clearCache() {
_cachedData = null;
}
}
4. 异常传播问题
// ❌ 问题:异常被意外吞噬
Future<String> problematicChain() {
return fetchData()
.then((data) => processData(data))
.then((processed) => saveData(processed))
.catchError((error) {
print('错误: $error');
return "默认值"; // 这里会掩盖真正的错误
});
}
// ✅ 解决方案:正确的异常处理
Future<String> improvedChain() async {
try {
String data = await fetchData();
String processed = await processData(data);
String saved = await saveData(processed);
return saved;
} on NetworkException catch (e) {
print('网络错误: $e');
throw Exception('网络连接失败,请稍后重试');
} on ValidationException catch (e) {
print('验证错误: $e');
throw Exception('数据验证失败: ${e.message}');
} catch (e) {
print('未知错误: $e');
rethrow; // 重新抛出异常
}
}
class NetworkException implements Exception {
final String message;
NetworkException(this.message);
@override
String toString() => 'NetworkException: $message';
}
class ValidationException implements Exception {
final String message;
ValidationException(this.message);
@override
String toString() => 'ValidationException: $message';
}
Future<String> fetchData() async => "原始数据";
Future<String> processData(String data) async => "处理后的$data";
Future<String> saveData(String data) async => "已保存的$data";
5. 测试异步代码
import 'package:test/test.dart';
// 测试异步函数
void main() {
group('异步函数测试', () {
test('测试成功情况', () async {
String result = await fetchUserName('123');
expect(result, equals('用户-123'));
});
test('测试错误情况', () async {
expect(
() => fetchUserName(''),
throwsA(isA<ArgumentError>()),
);
});
test('测试超时情况', () async {
expect(
() => slowOperation().timeout(Duration(seconds: 1)),
throwsA(isA<TimeoutException>()),
);
});
test('测试多个异步操作', () async {
List<String> results = await Future.wait([
fetchUserName('1'),
fetchUserName('2'),
fetchUserName('3'),
]);
expect(results, hasLength(3));
expect(results[0], equals('用户-1'));
});
});
}
Future<String> fetchUserName(String id) async {
if (id.isEmpty) {
throw ArgumentError('ID不能为空');
}
return await Future.delayed(
Duration(milliseconds: 100),
() => '用户-$id'
);
}
Future<String> slowOperation() async {
return await Future.delayed(
Duration(seconds: 5),
() => '慢操作完成'
);
}
总结
Future 是 Dart 异步编程的核心,掌握它对于编写高效的 Dart 应用程序至关重要。关键要点:
核心概念
- Future 表示异步操作的结果
- 三种状态:未完成、已完成有值、已完成有错误
- 支持链式调用和组合操作
最佳实践
- 优先使用 async/await - 代码更清晰易读
- 合理使用并行处理 - 提高性能
- 正确处理错误 - 使用 try-catch 或 catchError
- 避免不必要的 await - 直接返回 Future
- 及时清理资源 - 防止内存泄漏
性能优化
- 使用
Future.wait()进行并行处理 - 实现缓存机制避免重复请求
- 合理设置超时时间
- 使用连接池管理资源
错误处理
- 使用具体的异常类型
- 提供有意义的错误信息
- 实现重试机制
- 考虑降级方案
通过掌握这些概念和实践,您可以编写出高效、可靠的异步 Dart 代码。记住,异步编程的关键是理解操作的执行时序和正确处理各种边界情况。