面试题答案
一键面试实现方式
- 使用
Future.wait
:在Flutter中,可以使用Future.wait
方法来并发执行多个异步任务。Future.wait
接受一个Future
对象的列表,并返回一个新的Future
,这个新的Future
在所有传入的Future
都完成时完成。
Future<List<dynamic>> fetchData() async {
List<Future<dynamic>> futures = [
// 假设这是从不同API获取数据的异步函数
fetchDataFromAPI1(),
fetchDataFromAPI2(),
fetchDataFromAPI3()
];
return Future.wait(futures);
}
Future<dynamic> fetchDataFromAPI1() async {
// 模拟从API1获取数据
await Future.delayed(const Duration(seconds: 2));
return "Data from API1";
}
Future<dynamic> fetchDataFromAPI2() async {
// 模拟从API2获取数据
await Future.delayed(const Duration(seconds: 3));
return "Data from API2";
}
Future<dynamic> fetchDataFromAPI3() async {
// 模拟从API3获取数据
await Future.delayed(const Duration(seconds: 1));
return "Data from API3";
}
- 使用
async/await
处理结果:在调用fetchData
函数时,可以使用async/await
来等待所有任务完成并处理结果。
void main() async {
List<dynamic> results = await fetchData();
results.forEach((element) {
print(element);
});
}
可能遇到的问题及解决方法
- 某个任务失败:如果
Future.wait
中的任何一个Future
抛出异常,整个Future.wait
都会失败并抛出该异常。- 解决方法:可以使用
try-catch
块来捕获异常,并对失败的任务进行处理。例如,可以记录错误日志或者提供默认值。
- 解决方法:可以使用
Future<List<dynamic>> fetchData() async {
List<Future<dynamic>> futures = [
fetchDataFromAPI1(),
fetchDataFromAPI2(),
fetchDataFromAPI3()
];
try {
return await Future.wait(futures);
} catch (e) {
// 记录错误日志
print('An error occurred: $e');
// 返回默认值
return List.filled(futures.length, null);
}
}
- 资源消耗问题:如果并发的任务过多,可能会导致资源消耗过大,如内存、网络资源等。
- 解决方法:可以限制并发任务的数量。例如,可以使用
Stream
和StreamController
来实现一个任务队列,控制同时执行的任务数量。
- 解决方法:可以限制并发任务的数量。例如,可以使用
import 'dart:async';
class TaskQueue {
final int maxConcurrentTasks;
final Queue<Future<dynamic> Function()> taskQueue = Queue();
final List<Future<dynamic>> activeTasks = [];
final StreamController<List<dynamic>> _resultController = StreamController();
Stream<List<dynamic>> get results => _resultController.stream;
TaskQueue(this.maxConcurrentTasks);
void addTask(Future<dynamic> Function() task) {
taskQueue.add(task);
_startNextTask();
}
void _startNextTask() {
while (activeTasks.length < maxConcurrentTasks && taskQueue.isNotEmpty) {
final task = taskQueue.removeFirst();
final future = task();
activeTasks.add(future);
future.then((value) {
activeTasks.remove(future);
_startNextTask();
_resultController.add([...activeTasks, value]);
}).catchError((error) {
activeTasks.remove(future);
_startNextTask();
_resultController.addError(error);
});
}
}
void close() {
_resultController.close();
}
}
使用示例:
void main() async {
final taskQueue = TaskQueue(2);
taskQueue.addTask(fetchDataFromAPI1);
taskQueue.addTask(fetchDataFromAPI2);
taskQueue.addTask(fetchDataFromAPI3);
taskQueue.results.listen((results) {
print('Current results: $results');
}, onError: (error) {
print('Error: $error');
}, onDone: () {
print('All tasks completed');
taskQueue.close();
});
}