Skip to content

异步编程

异步编程允许你的程序在不阻塞执行的情况下执行任务。Dart 通过 Futureasyncawait 提供出色的异步操作支持。

Future

Future 表示将来某个时刻可用的值。

dart
Future<String> fetchUserData() {
  return Future.delayed(
    Duration(seconds: 2),
    () => '用户数据已加载',
  );
}

void main() {
  print('获取数据中...');
  fetchUserData().then((data) {
    print(data);
  });
  print('请求已发送');
}
// 输出:
// 获取数据中...
// 请求已发送
// 用户数据已加载(2秒后)

async 和 await

asyncawait 关键字使异步代码看起来像同步代码:

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');
  }
}

最佳实践

  1. 始终使用 async/await 以获得更清晰的代码
  2. 使用 try-catch 处理错误
  3. 对并行操作使用 Future.wait
  4. 对连续数据优先使用 stream
  5. 不要忘记 await - 常见错误!

下一步