面试题答案
一键面试- 错误处理
- 使用
try - catch
块包裹每个await
语句,以便捕获单个任务中的异常。例如:
Future<void> performTasks() async { List<Future<void>> tasks = [task1(), task2(), task3()]; for (var task in tasks) { try { await task; } catch (e) { // 处理错误,如记录日志 print('Error occurred in task: $e'); } } } Future<void> task1() async { // 模拟异步任务 await Future.delayed(const Duration(seconds: 1)); // 可能会抛出异常 throw Exception('Task 1 error'); } Future<void> task2() async { await Future.delayed(const Duration(seconds: 1)); print('Task 2 completed'); } Future<void> task3() async { await Future.delayed(const Duration(seconds: 1)); print('Task 3 completed'); }
- 另一种方式是使用
Future.wait
结合catchError
。Future.wait
可以并发执行多个Future
,并返回一个新的Future
,当所有Future
都完成时,新的Future
完成。catchError
可以捕获其中任何一个Future
抛出的异常。
Future<void> performTasks() async { List<Future<void>> tasks = [task1(), task2(), task3()]; try { await Future.wait(tasks, eagerError: true).catchError((e) { // 处理错误,如记录日志 print('Error occurred in task: $e'); }); } catch (e) { // 这里也可以捕获异常,但一般在catchError中处理就好 print('Another error handling: $e'); } } Future<void> task1() async { await Future.delayed(const Duration(seconds: 1)); throw Exception('Task 1 error'); } Future<void> task2() async { await Future.delayed(const Duration(seconds: 1)); print('Task 2 completed'); } Future<void> task3() async { await Future.delayed(const Duration(seconds: 1)); print('Task 3 completed'); }
- 使用
- 回滚操作
- 对于有状态变化的任务,在任务执行前记录初始状态,若任务执行过程中抛出异常,恢复到初始状态。例如,在数据库操作中,若插入数据失败,需要回滚插入操作。
Future<void> insertData() async { var initialData = await fetchData(); try { await database.insert('table', {'data': 'new data'}); } catch (e) { // 回滚操作,如删除刚插入的数据(如果有部分插入成功)或恢复到初始数据状态 await database.delete('table', where: {'data': 'new data'}); // 或者恢复到初始数据 await database.update('table', initialData); } }
- 优化并发任务性能
- 设置合理的并发数量:使用
dart:async
库中的Stream
和StreamController
来实现有限并发。例如,可以使用Stream
来管理任务队列,并且每次只处理固定数量的任务。
Future<void> performTasks() async { int maxConcurrent = 2; List<Future<void>> tasks = [task1(), task2(), task3(), task4()]; StreamController<Future<void>> controller = StreamController<Future<void>>(); tasks.forEach((task) => controller.add(task)); controller.close(); List<Future<void>> activeTasks = []; await for (var task in controller.stream) { activeTasks.add(task); if (activeTasks.length >= maxConcurrent) { await Future.any(activeTasks).then((value) { activeTasks.remove(value); }); } } await Future.wait(activeTasks); } Future<void> task1() async { await Future.delayed(const Duration(seconds: 1)); print('Task 1 completed'); } Future<void> task2() async { await Future.delayed(const Duration(seconds: 1)); print('Task 2 completed'); } Future<void> task3() async { await Future.delayed(const Duration(seconds: 1)); print('Task 3 completed'); } Future<void> task4() async { await Future.delayed(const Duration(seconds: 1)); print('Task 4 completed'); }
- 缓存结果:如果某些异步任务的结果是固定不变或者变化频率很低的,可以缓存这些结果,避免重复执行任务。例如,使用
Map
来缓存Future
的结果。
Map<String, Future<dynamic>> cache = {}; Future<dynamic> getCachedData(String key) { if (!cache.containsKey(key)) { cache[key] = performAsyncTask(); } return cache[key]!; } Future<dynamic> performAsyncTask() async { await Future.delayed(const Duration(seconds: 1)); return 'result'; }
- 设置合理的并发数量:使用