MST
星途 面试题库

面试题:Flutter中async/await与Future的深度理解

在Flutter中,async函数总会返回一个Future。请解释async函数内部是如何将返回值封装成Future的,以及await关键字在处理Future时的具体机制。如果在一个async函数中有多个await操作,它们是顺序执行还是并行执行?如何控制它们的执行顺序以优化性能?
20.1万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

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
}

控制执行顺序以优化性能

  1. 并行执行:如果多个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
}
  1. 按顺序执行,但利用缓存:如果某些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;
  }
}
  1. 条件执行:根据某些条件决定执行哪个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);
}