diff --git "a/docs/flutter_knowledge/asynchronous/async\345\222\214await.md" "b/docs/flutter_knowledge/asynchronous/async\345\222\214await.md" new file mode 100644 index 0000000000000000000000000000000000000000..a92fc2427a912c20c3e9c2e1615ccd7541f6765a --- /dev/null +++ "b/docs/flutter_knowledge/asynchronous/async\345\222\214await.md" @@ -0,0 +1,176 @@ +在Dart中,异步编程是必不可少的,尤其是处理I/O操作(如网络请求、文件操作或数据库查询)。现在介绍常用的异步编程:`async` 和 `await`,剖析其优缺点及应用场景。 + +# async 和 await + +`async` 和 `await` 是 Dart 中用于简化异步编程的重要特性。它们的设计让代码结构更直观,但也有一些限制和需要注意的地方。 + +------ + +### **优点** + +#### 1. **简化异步代码结构** + +- 使用 `async` 和 `await`,异步代码看起来像同步代码,逻辑更加线性,易于理解和维护。 + +- 示例: + + ```dart + // 使用 async/await + Future fetchData() async { + try { + final response = await http.get(Uri.parse('https://api.example.com')); + print(response.body); + } catch (e) { + print('Error: $e'); + } + } + ``` + +与回调方式相比: + +```dart +// 使用回调 +void fetchData() { + http.get(Uri.parse('https://api.example.com')).then((response) { + print(response.body); + }).catchError((e) { + print('Error: $e'); + }); +} +``` + +------ + +#### 2. **更高的可读性和可维护性** + +- 消除了嵌套的回调地狱,让代码更加整洁,减少逻辑错误的可能性。 + +#### 3. **与 Dart 的同步代码无缝集成** + +- 可以在同步代码中调用 `async` 函数,并等待其结果完成,而不影响代码的整体结构。 + +#### 4. **任务依赖更容易实现** + +- 通过 `await` 的线性逻辑,可以自然地表达任务之间的依赖关系。 + +- 示例: + + ```dart + Future processTasks() async { + final result1 = await task1(); + final result2 = await task2(result1); + final result3 = await task3(result2); + print(result3); + } + ``` + +------ + +### **缺点** + +#### 1. **无法并发执行** + +- 如果需要并发执行多个异步任务,单纯使用 `async/await` 会导致这些任务按顺序执行,降低效率。 + +- 示例(任务依次执行,耗时更长): + + ```dart + Future sequentialTasks() async { + final result1 = await task1(); + final result2 = await task2(); + final result3 = await task3(); + } + ``` + +**解决方法:** 使用 `Future.wait` 实现并发: + +```dart +Future concurrentTasks() async { + final results = await Future.wait([task1(), task2(), task3()]); +} +``` + +#### 2. **错误捕获可能遗漏** + +- 如果在异步任务中没有正确使用 `try-catch`,错误可能会被吞掉或传播到全局,难以调试。 + +- 示例(错误未捕获的情况): + + ```dart + Future fetchData() async { + await someAsyncFunction(); // 如果函数内部抛出异常,但没有 try-catch,错误可能未捕获 + } + ``` + +#### 3. **不能直接取消任务** + +- Dart 的 `async/await` 不提供直接取消正在执行的任务。要实现任务的取消,需要使用其他策略,例如使用 Stream 或设计自定义的控制逻辑。 + +#### 4. **可能导致性能问题(过多的等待)** + +- 如果不合理地使用 `await`,例如在不必要的地方等待某些任务完成,会拖慢整体性能。 + +- 示例(不必要的阻塞): + + ```dart + Future fetchData() async { + for (var i = 0; i < 10; i++) { + final data = await fetchSingleItem(i); // 每次都等待一个请求完成 + print(data); + } + } + ``` + +**优化方法:** 并发处理任务: + +```dart +dart Future fetchData() async { + final tasks = List.generate(10, (i) => fetchSingleItem(i)); + final results = await Future.wait(tasks); + results.forEach(print); +} +``` + + + +------ + +### **适用场景** + +#### 适合: + +1. 单任务的异步操作 + - 如网络请求、文件读取等单次异步任务。 +2. 任务之间有依赖关系 + - 需要按照顺序执行多个异步操作。 +3. 需要简洁的代码逻辑 + - 简化回调地狱,提高代码可读性。 + +#### 不适合: + +1. 需要并发执行多个任务 + - 直接使用 `async/await` 会导致任务按顺序执行。 +2. 实时更新的数据流 + - 例如监听事件流,`async/await` 不能直接处理 `Stream`。 +3. 需要取消任务的场景 + - `async/await` 无法直接中止正在进行的任务。 + +------ + +### **总结** + +#### 优点: + +- 让异步代码更清晰、结构化,减少复杂度。 +- 更高的可维护性和可读性。 +- 内置的错误处理机制。 +- 易于表达任务的依赖关系。 + +#### 缺点: + +- 无法并发执行,可能降低效率。 +- 仅适用于 `Future`,限制较多。 +- 不支持任务取消。 +- 对复杂异步场景(如并发任务、实时数据)支持不足。 + +在实际开发中,应根据具体场景结合 `Future.wait`、`Stream` 等工具,合理利用 `async/await` 提升代码质量和性能。