面试题答案
一键面试async/await基本原理
- async:
async
关键字用于定义一个异步函数。当一个函数被声明为async
时,该函数始终返回一个Future
对象。即使函数内部没有显式地返回Future
,Dart也会自动将其返回值包装成一个已完成的Future
。例如:
这里asyncFunction() async { return 42; }
asyncFunction
虽然返回的是一个普通整数42
,但实际上返回的是一个已完成的Future<int>
,值为42
。 - await:
await
关键字只能在async
函数内部使用。它用于暂停当前async
函数的执行,直到其等待的Future
完成(无论是成功完成还是因错误而失败)。当Future
完成时,await
表达式会返回Future
的结果。如果Future
因错误而失败,await
会抛出该错误,就像在普通代码中抛出异常一样。例如:
这里Future<int> fetchData() async { return 10; } asyncFunction() async { int result = await fetchData(); print(result); // 输出10 }
await fetchData()
暂停了asyncFunction
的执行,直到fetchData
返回的Future
完成,然后将Future
的结果赋值给result
。
简化异步操作的方式
- 代码结构更清晰:在没有
async/await
之前,处理异步操作通常使用Future
的链式调用,如.then()
和.catchError()
。这种方式在处理多个异步操作时,代码会变得非常复杂,形成所谓的“回调地狱”。而async/await
使异步代码看起来更像同步代码,提高了代码的可读性和可维护性。例如:- 传统链式调用方式:
Future<int> fetchData1() async { return 10; } Future<int> fetchData2(int value) async { return value * 2; } Future<int> fetchData3(int value) async { return value + 5; } chainCall() { fetchData1() .then((value1) => fetchData2(value1)) .then((value2) => fetchData3(value2)) .then((finalValue) => print(finalValue)) .catchError((error) => print('Error: $error')); }
- 使用
async/await
方式:
可以看到,asyncFunction() async { try { int value1 = await fetchData1(); int value2 = await fetchData2(value1); int finalValue = await fetchData3(value2); print(finalValue); } catch (error) { print('Error: $error'); } }
async/await
方式的代码结构更接近同步代码,逻辑更清晰。 - 异常处理更方便:
async/await
可以使用传统的try - catch
块来处理异步操作中的异常,而不需要像链式调用那样使用.catchError()
方法,使异常处理代码更统一和直观。
常见使用场景及代码示例
- 网络请求场景:
- 在Flutter中使用
http
库进行网络请求时,async/await
非常有用。首先需要导入http
库:import 'package:http/http.dart' as http;
这里Future<String> fetchDataFromServer() async { Uri url = Uri.parse('https://example.com/api/data'); http.Response response = await http.get(url); if (response.statusCode == 200) { return response.body; } else { throw Exception('Failed to load data'); } } asyncFunction() async { try { String data = await fetchDataFromServer(); print(data); } catch (error) { print('Error: $error'); } }
await http.get(url)
暂停执行,直到网络请求完成,然后根据响应状态码处理结果或抛出异常。 - 在Flutter中使用
- 文件读取场景:
- 使用
dart:io
库进行文件读取,首先导入dart:io
:import 'dart:io';
这里Future<String> readFile() async { File file = File('path/to/your/file.txt'); try { return await file.readAsString(); } catch (error) { throw Exception('Failed to read file: $error'); } } asyncFunction() async { try { String content = await readFile(); print(content); } catch (error) { print('Error: $error'); } }
await file.readAsString()
暂停执行,直到文件读取操作完成,然后返回文件内容或抛出异常。 - 使用