面试题答案
一键面试async函数返回值封装成Future的机制
当一个函数被声明为async
时,无论其返回值是什么,Dart会自动将其包装成一个Future
。如果函数正常返回一个值,该值会被包装进一个已完成(completed)状态且带有该返回值的Future
。例如:
asyncFunction() async {
return 42;
}
// 实际返回的是一个Future<int>,其状态为已完成,值为42
如果函数抛出异常,那么会返回一个已完成状态但带有该异常的Future
。例如:
asyncFunction() async {
throw 'An error occurred';
}
// 实际返回的是一个Future,其状态为已完成,带有抛出的异常
await关键字处理Future的机制
await
关键字只能在async
函数内部使用。它的作用是暂停当前async
函数的执行,直到其等待的Future
完成(resolved,即变为已完成状态)。当Future
完成时,await
表达式会返回Future
的结果(如果是成功完成),或者抛出Future
的异常(如果是异常完成)。例如:
Future<int> fetchData() async {
return 42;
}
asyncFunction() async {
int result = await fetchData();
print(result); // 输出 42
}
多个await操作的执行顺序
在一个async
函数中的多个await
操作是顺序执行的。每次遇到await
,当前async
函数会暂停执行,直到被等待的Future
完成,然后继续执行await
之后的代码。例如:
Future<int> fetchData1() async {
await Future.delayed(Duration(seconds: 1));
return 42;
}
Future<int> fetchData2() async {
await Future.delayed(Duration(seconds: 1));
return 100;
}
asyncFunction() async {
int result1 = await fetchData1();
int result2 = await fetchData2();
print(result1); // 1秒后输出 42
print(result2); // 再过1秒后输出 100
}
控制执行顺序以优化性能
- 并行执行:如果多个
Future
之间没有依赖关系,可以使用Future.wait
来并行执行它们。Future.wait
接受一个Future
列表,并返回一个新的Future
,这个新的Future
会在所有传入的Future
都完成时完成。例如:
Future<int> fetchData1() async {
await Future.delayed(Duration(seconds: 1));
return 42;
}
Future<int> fetchData2() async {
await Future.delayed(Duration(seconds: 1));
return 100;
}
asyncFunction() async {
List<Future<int>> futures = [fetchData1(), fetchData2()];
List<int> results = await Future.wait(futures);
print(results[0]); // 1秒后输出 42
print(results[1]); // 1秒后输出 100
}
- 按顺序执行,但利用缓存:如果某些
Future
的结果可能会被重复使用,可以考虑缓存这些结果。例如,可以使用compute
函数(用于在隔离区(isolate)中执行计算密集型任务)并缓存其结果。
int expensiveCalculation(int num) {
// 模拟耗时计算
return num * num;
}
Future<int> cachedCompute(int num, Map<int, int> cache) async {
if (cache.containsKey(num)) {
return cache[num]!;
} else {
int result = await compute(expensiveCalculation, num);
cache[num] = result;
return result;
}
}
- 条件执行:根据某些条件决定执行哪个
Future
。例如:
Future<int> fetchData1() async {
return 42;
}
Future<int> fetchData2() async {
return 100;
}
asyncFunction(bool condition) async {
Future<int> futureToAwait = condition? fetchData1() : fetchData2();
int result = await futureToAwait;
print(result);
}