Dart 并发编程详细总结2-案例

59 阅读3分钟
import 'dart:async';
import 'dart:isolate';
import 'dart:math';

/// Dart 并发编程实践示例
///
/// 这个文件包含了各种并发编程场景的完整示例,可以直接运行测试

void main() async {
  print('🚀 Dart 并发编程示例开始');

  // 1. Future 和 async/await 示例
  await futureExamples();

  // 2. Stream 流式编程示例
  await streamExamples();

  // 3. Isolate 隔离区示例
  await isolateExamples();

  // 4. 实际应用场景示例
  await practicalExamples();

  print('✅ 所有示例执行完成');
}

/// Future 和 async/await 示例
Future<void> futureExamples() async {
  print('\n📦 Future 示例');

  // 基本 Future 操作
  await basicFutureOperations();

  // 并发执行多个任务
  await parallelExecution();

  // 错误处理
  await errorHandlingExample();
}

/// 基本 Future 操作
Future<void> basicFutureOperations() async {
  print('\n1. 基本 Future 操作');

  // 创建立即完成的 Future
  final immediate = Future.value('立即完成');
  print('立即值: ${await immediate}');

  // 延迟执行
  final delayed = Future.delayed(
    Duration(milliseconds: 500),
    () => '延迟500ms完成',
  );
  print('延迟值: ${await delayed}');

  // 链式调用
  final chainResult = await Future.value(
    'hello',
  ).then((value) => value.toUpperCase()).then((value) => '$value WORLD');
  print('链式调用结果: $chainResult');
}

/// 并发执行多个任务
Future<void> parallelExecution() async {
  print('\n2. 并发执行示例');

  final stopwatch = Stopwatch()..start();

  // 创建多个异步任务
  final tasks = [
    simulateNetworkCall('用户数据', 1000),
    simulateNetworkCall('商品列表', 1500),
    simulateNetworkCall('订单历史', 800),
  ];

  // 并发等待所有任务完成
  final results = await Future.wait(tasks);

  stopwatch.stop();
  print('并发执行结果:');
  results.forEach(print);
  print('总耗时: ${stopwatch.elapsedMilliseconds}ms');

  // 如果顺序执行,总耗时应该是 1000 + 1500 + 800 = 3300ms
  // 并发执行只需要 max(1000, 1500, 800) = 1500ms 左右
}

/// 模拟网络请求
Future<String> simulateNetworkCall(String dataType, int delayMs) async {
  await Future.delayed(Duration(milliseconds: delayMs));
  return '$dataType 加载完成 (${delayMs}ms)';
}

/// 错误处理示例
Future<void> errorHandlingExample() async {
  print('\n3. 错误处理示例');

  // try-catch 方式
  try {
    await Future.delayed(Duration(milliseconds: 100), () {
      throw Exception('模拟网络错误');
    });
  } catch (e) {
    print('捕获异常: $e');
  }

  // Future.catchError 方式
  final result = await Future.value('正常数据')
      .then((value) {
        if (Random().nextBool()) {
          throw Exception('随机错误');
        }
        return value;
      })
      .catchError((error) => '默认数据: $error')
      .whenComplete(() => print('清理资源'));

  print('最终结果: $result');

  // 超时处理
  try {
    await Future.delayed(
      Duration(seconds: 2),
      () => '慢响应',
    ).timeout(Duration(seconds: 1));
  } on TimeoutException {
    print('请求超时');
  }
}

/// Stream 流式编程示例
Future<void> streamExamples() async {
  print('\n🌊 Stream 示例');

  await basicStreamOperations();
  await streamTransformations();
  await broadcastStreamExample();
}

/// 基本 Stream 操作
Future<void> basicStreamOperations() async {
  print('\n1. 基本 Stream 操作');

  // 从 Iterable 创建
  final numberStream = Stream.fromIterable([1, 2, 3, 4, 5]);

  print('数字流:');
  await for (int number in numberStream) {
    print('  收到数字: $number');
  }

  // 定期发射数据 (只取前3个)
  print('\n定期数据流:');
  await Stream.periodic(
    Duration(milliseconds: 200),
    (count) => 'tick $count',
  ).take(3).forEach(print);
}

/// Stream 转换操作
Future<void> streamTransformations() async {
  print('\n2. Stream 转换操作');

  final sourceStream = Stream.fromIterable([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

  print('原始数据: 1-10');

  // 链式转换
  final transformedStream = sourceStream
      .where((x) => x % 2 == 0) // 过滤偶数
      .map((x) => x * x) // 平方
      .take(3); // 取前3个

  print('偶数平方(前3个):');
  await transformedStream.forEach((value) => print('  $value'));

  // 异步转换
  print('\n异步转换:');
  final asyncStream = Stream.fromIterable(['a', 'b', 'c']).asyncMap((
    letter,
  ) async {
    await Future.delayed(Duration(milliseconds: 100));
    return letter.toUpperCase();
  });

  await asyncStream.forEach(print);
}

/// Broadcast Stream 示例
Future<void> broadcastStreamExample() async {
  print('\n3. Broadcast Stream 示例');

  final controller = StreamController<String>.broadcast();

  // 多个监听器
  controller.stream.listen((data) => print('监听器1: $data'));
  controller.stream.listen((data) => print('监听器2: $data'));

  // 发送数据
  controller.add('广播消息 1');
  controller.add('广播消息 2');

  await Future.delayed(Duration(milliseconds: 100));
  controller.close();
}

/// Isolate 隔离区示例
Future<void> isolateExamples() async {
  print('\n🔀 Isolate 示例');

  await basicIsolateExample();
  await heavyComputationExample();
}

/// 基础 Isolate 示例
Future<void> basicIsolateExample() async {
  print('\n1. 基础 Isolate 通信');

  final receivePort = ReceivePort();

  // 启动 Isolate
  await Isolate.spawn(_isolateEntryPoint, {
    'sendPort': receivePort.sendPort,
    'message': '来自主 Isolate 的消息',
  });

  // 接收来自 Isolate 的消息
  final response = await receivePort.first;
  print('收到 Isolate 响应: $response');
}

/// Isolate 入口点函数
void _isolateEntryPoint(Map<String, dynamic> params) {
  final SendPort sendPort = params['sendPort'];
  final String message = params['message'];

  // 处理消息并发送响应
  final response = '处理完成: $message';
  sendPort.send(response);
}

/// CPU 密集型计算示例
Future<void> heavyComputationExample() async {
  print('\n2. CPU 密集型计算 (使用 compute)');

  final numbers = List.generate(1000000, (i) => i);

  print('开始计算大数组的和...');
  final stopwatch = Stopwatch()..start();

  // 使用 compute 在后台 Isolate 中计算
  final result = await compute(_calculateSum, numbers);

  stopwatch.stop();
  print('计算结果: $result');
  print('计算耗时: ${stopwatch.elapsedMilliseconds}ms');
}

/// 计算数组和的函数 (必须是顶级函数)
int _calculateSum(List<int> numbers) {
  return numbers.reduce((a, b) => a + b);
}

/// 实际应用场景示例
Future<void> practicalExamples() async {
  print('\n🏗️ 实际应用示例');

  await dataFetchingService();
  await reactiveDataModel();
}

/// 数据获取服务示例
Future<void> dataFetchingService() async {
  print('\n1. 数据获取服务');

  final service = DataService();

  // 获取多个用户数据
  final userIds = [1, 2, 3, 4, 5];
  final users = await service.fetchMultipleUsers(userIds);

  print('获取到 ${users.length} 个用户:');
  users.forEach((user) => print('  ${user['name']} (ID: ${user['id']})'));
}

/// 响应式数据模型示例
Future<void> reactiveDataModel() async {
  print('\n2. 响应式数据模型');

  final repository = UserRepository();

  // 监听用户数据变化
  final subscription = repository.users.listen((users) {
    print('用户数据更新: ${users.length} 个用户');
  });

  // 模拟搜索操作
  repository.search('张');
  await Future.delayed(Duration(milliseconds: 100));

  repository.search('李');
  await Future.delayed(Duration(milliseconds: 100));

  repository.search('王');
  await Future.delayed(Duration(milliseconds: 500));

  subscription.cancel();
  repository.dispose();
}

/// 数据获取服务
class DataService {
  /// 并发获取多个用户
  Future<List<Map<String, dynamic>>> fetchMultipleUsers(
    List<int> userIds,
  ) async {
    final futures = userIds.map((id) => _fetchUser(id));
    return Future.wait(futures);
  }

  /// 模拟获取单个用户
  Future<Map<String, dynamic>> _fetchUser(int id) async {
    // 模拟网络延迟
    await Future.delayed(Duration(milliseconds: 100 + Random().nextInt(200)));

    final names = ['张三', '李四', '王五', '赵六', '钱七'];
    return {
      'id': id,
      'name': names[id % names.length],
      'email': 'user$id@example.com',
    };
  }
}

/// 响应式用户数据仓库
class UserRepository {
  final _usersController =
      StreamController<List<Map<String, dynamic>>>.broadcast();
  final _searchController = StreamController<String>();
  late StreamSubscription _searchSubscription;

  Stream<List<Map<String, dynamic>>> get users => _usersController.stream;

  UserRepository() {
    // 设置搜索流处理
    _searchSubscription = _searchController.stream
        .distinct() // 去重
        .asyncMap((query) => _searchUsers(query)) // 异步搜索
        .listen((users) => _usersController.add(users));
  }

  void search(String query) {
    _searchController.add(query);
  }

  /// 模拟用户搜索
  Future<List<Map<String, dynamic>>> _searchUsers(String query) async {
    await Future.delayed(Duration(milliseconds: 200)); // 模拟搜索延迟

    final allUsers = [
      {'id': 1, 'name': '张三丰'},
      {'id': 2, 'name': '李白'},
      {'id': 3, 'name': '王维'},
      {'id': 4, 'name': '赵云'},
      {'id': 5, 'name': '钱学森'},
    ];

    return allUsers
        .where((user) => (user['name'] as String).contains(query))
        .toList();
  }

  void dispose() {
    _searchSubscription.cancel();
    _usersController.close();
    _searchController.close();
  }
}

// 为了支持 compute 函数,需要添加这个导入
// 在实际的 Flutter 项目中,应该使用: import 'package:flutter/foundation.dart';
// 这里我们提供一个简化版本的实现
Future<R> compute<Q, R>(R Function(Q) callback, Q message) async {
  final receivePort = ReceivePort();

  await Isolate.spawn(_computeEntryPoint, {
    'message': message,
    'sendPort': receivePort.sendPort,
  });

  return await receivePort.first as R;
}

void _computeEntryPoint(Map<String, dynamic> params) {
  final List<int> message = params['message'];
  final SendPort sendPort = params['sendPort'];

  try {
    // 直接在这里计算,避免函数类型传递的问题
    final result = message.reduce((a, b) => a + b);
    sendPort.send(result);
  } catch (error) {
    sendPort.send(error);
  }
}