异步编程
异步编程允许你的程序在不阻塞执行的情况下执行任务。Dart 通过 Future、async 和 await 提供出色的异步操作支持。
Future
Future 表示将来某个时刻可用的值。
dart
Future<String> fetchUserData() {
return Future.delayed(
Duration(seconds: 2),
() => '用户数据已加载',
);
}
void main() {
print('获取数据中...');
fetchUserData().then((data) {
print(data);
});
print('请求已发送');
}
// 输出:
// 获取数据中...
// 请求已发送
// 用户数据已加载(2秒后)async 和 await
async 和 await 关键字使异步代码看起来像同步代码:
dart
Future<String> fetchUserData() async {
await Future.delayed(Duration(seconds: 2));
return '用户数据已加载';
}
void main() async {
print('获取数据中...');
String data = await fetchUserData();
print(data);
print('完成');
}错误处理
dart
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 1));
throw Exception('加载数据失败');
}
void main() async {
try {
String data = await fetchData();
print(data);
} catch (e) {
print('错误:$e');
} finally {
print('清理');
}
}多个 Future
Future.wait
等待多个 future 完成:
dart
Future<void> loadData() async {
var results = await Future.wait([
fetchUser(),
fetchPosts(),
fetchComments(),
]);
print('用户:${results[0]}');
print('帖子:${results[1]}');
print('评论:${results[2]}');
}Stream
Stream 提供异步事件序列:
dart
Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
void main() async {
await for (var number in countStream(5)) {
print(number);
}
}完整示例
dart
class ApiService {
Future<Map<String, dynamic>> fetchUser(int id) async {
await Future.delayed(Duration(seconds: 1));
return {'id': id, 'name': '用户 $id', 'email': 'user$id@example.com'};
}
Future<List<String>> fetchPosts(int userId) async {
await Future.delayed(Duration(seconds: 1));
return ['帖子 1', '帖子 2', '帖子 3'];
}
Stream<String> fetchComments(int postId) async* {
for (int i = 1; i <= 3; i++) {
await Future.delayed(Duration(milliseconds: 500));
yield '帖子 $postId 的评论 $i';
}
}
}
void main() async {
var api = ApiService();
try {
// 获取用户
print('获取用户中...');
var user = await api.fetchUser(1);
print('用户:${user['name']}');
// 获取帖子
print('\n获取帖子中...');
var posts = await api.fetchPosts(user['id']);
print('帖子:${posts.length}');
// 流式获取评论
print('\n获取评论中...');
await for (var comment in api.fetchComments(1)) {
print(comment);
}
print('\n所有数据已加载!');
} catch (e) {
print('错误:$e');
}
}最佳实践
- 始终使用
async/await以获得更清晰的代码 - 使用 try-catch 处理错误
- 对并行操作使用
Future.wait - 对连续数据优先使用 stream
- 不要忘记
await- 常见错误!