Flutter asynchronous 异步编程技巧

简介: 本文深入探讨了Flutter中的异步编程技巧,包括Future、Microtask及并发处理的最佳实践。文章详细讲解了Future.wait、FutureBuilder和Microtask的应用,帮助开发者提升应用性能。通过实例演示了如何利用Future.wait实现并发执行,FutureBuilder简化UI构建,以及Microtask的高优先级执行特性。适合希望优化Flutter应用异步性能的开发者阅读。

Flutter asynchronous 异步编程技巧

flutter async

视频

https://youtu.be/Hn_PxYzsG8U

https://www.bilibili.com/video/BV1g1421t7Ag/

前言

原文 Flutter 异步编程技巧与最佳实践

深入探讨 Flutter 中 Future、Microtask 和并发处理的高效用法,为您的应用程序带来卓越的异步性能。包含 Future.wait、FutureBuilder 和 Microtask 任务分解等实用技巧。

参考

async 官方说明

AsyncSnapshot 类说明

Dart asynchronous programming: Isolates and event loops

步骤

Future.wait

Future.wait() 是 Dart 中一个非常有用的异步操作方法,它允许我们并发执行多个异步任务,并在所有任务完成后统一处理结果。

Future.wait() 的主要特点如下:

  1. 并发执行:它允许我们并发执行多个异步操作,而不需要一个一个地等待它们完成。这对于需要汇总多个数据源的场景非常有用。
  2. 统一结果处理:当所有异步操作都完成后,Future.wait() 会将它们的结果整合成一个 List,我们可以统一地处理这些结果。
  3. 错误处理:如果任何一个异步操作抛出异常,Future.wait() 也会将这个异常抛出,我们可以在外层捕获并处理。
  4. 取消机制:如果我们在 Future.wait() 完成之前取消了它,那么其内部的所有异步操作也会被取消。
  5. 灵活使用:我们可以根据需求,自由地组合各种异步操作,如 API 请求、文件 I/O 等,并用 Future.wait() 一起执行。

假设你有多个计算密集型的异步调用需要执行。每个调用完成都需要几秒钟的时间,如下代码中的延迟所示。

Future<void> asyncOperation1() async {
   await Future.delayed(
       Duration(seconds: 2), () => print('Async Operation 1'));
 }

 Future<void> asyncOperation2() async {
   await Future.delayed(
       Duration(seconds: 3), () => print('Async Operation 2'));
 }

 Future<void> asyncOperation3() async {
   await Future.delayed(
       Duration(seconds: 4), () => print('Async Operation 3'));
 }

如果你使用 await 方式执行它们,完成时间将是每个操作执行时间的总和,9 秒钟。

void awaitApproach() async {
   print('Start: ${DateTime.now()}');
   await asyncOperation1();
   await asyncOperation2();
   await asyncOperation3();
   print('End: ${DateTime.now()}');
}

/*
Start: 2024–02–18 12:08:30.205252
Async Operation 1
Async Operation 2
Async Operation 3
End: 2024–02–18 12:08:39.221854
*/

使用 Future.wait 将会看到是并行执行的 , 5 秒钟。

void futureWaitApproach() async {
   print('Start: ${DateTime.now()}');
   await Future.wait([asyncOperation1(), asyncOperation2(), asyncOperation3()]);
   print('End: ${DateTime.now()}');
}

/*
Start: 2024-02-18 12:16:20.796960
Async Operation 1
Async Operation 2
Async Operation 3
End: 2024-02-18 12:16:24.804660
*/

Future.wait并行

Future.wait 并发执行

Future.wait 总是返回一个 List。

如果是不同的返回值,返回类型 List<Object> , 你可以通过枚举或者下标方式访问 result[0]

 var futures = [
   Future.value(42),
   Future.value('hello'),
 ];

 var result = await Future.wait(futures);
 print(result); // [42, hello]
 print(result[0].runtimeType); // int
 print(result[1].runtimeType); // String
 print(result.runtimeType); // List<Object>

FutureBuilder

FutureBuilder 可以帮助您减少样板代码和复杂性,适用于需要根据异步交互构建 widget 小部件的场景。它提供了一种直接的方法来访问 Future 的 snapshot 快照状态,并相应地处理 UI。

AsyncSnapshot 参考

https://api.flutter.dev/flutter/widgets/AsyncSnapshot-class.html

举例:

FutureBuilder(
 future: _fetchData(), // 异步操作, 比如通过 api 拉取数据
 builder: (context, snapshot) {
   // 根据异步操作的状态更新UI
   if (snapshot.connectionState == ConnectionState.waiting) {
     return CircularProgressIndicator(); // 正在加载
   } else if (snapshot.hasError) {
     return Text('Error: ${snapshot.error}'); // 发生错误
   } else {
     final data = snapshot.data;
     return ListView.builder(
       itemCount: data.length,
       itemBuilder: (context, index) {
         return Text('Item ${index}: $data[index]');
       },
     ); // 加载成功
   }
 },
)

FutureBuilder 的使用场景是小 widget ,他需要 StatefulWidget 的支持,所以性能一般,如果你是大范围使用,还是要考虑专业的状态管理组件 provider getx bloc 这种。

microtask

Microtask queue and event queue flow diagram in Flutter.

Microtasks 是 Dart 语言中的一种特殊任务类型,它们会在当前事件循环的末尾执行。与普通的异步任务(Future)不同,Microtasks 具有以下特点:

  1. 优先级高于 Future: Microtasks 的执行优先级高于 Future,也就是说,即使有一个正在执行的 Future,如果有 Microtasks 需要执行,它们也会先于 Future 执行。
  2. 立即执行: 当 Microtasks 被添加到 event queue 中时,它们会立即执行,而不会等待当前事件循环结束。
  3. 同步执行: 与 Future 不同,Microtasks 是同步执行的,它们会在当前事件循环的末尾,一个接一个地执行完毕。

例子

void main() {
 print('Start');

 // 添加一个 Microtask
 scheduleMicrotask(() {
   print('Microtask 1');
 });

 // 添加一个 Future
 Future(() {
   print('Future');
 });

 // 添加另一个 Microtask
 scheduleMicrotask(() {
   print('Microtask 2');
 });

 print('End');
}

输出

Start
End
Microtask 1
Microtask 2
Future

从输出可以看出:

  1. 两个 Microtasks 先于 Future 执行,体现了 Microtasks 的高优先级。
  2. 两个 Microtasks 是立即执行的,并且是同步执行的,一个接一个地执行完毕。
  3. Future 最后执行,因为它的优先级低于 Microtasks。

Microtasks 通常用于以下场景:

  1. 在 Widget 构建过程中更新状态:当 Widget 正在构建时,可以使用 Microtasks 来更新 Widget 的状态。
  2. 执行一些低开销的任务:如果一个任务执行开销很低,又需要立即执行,可以使用 Microtasks。
  3. 处理异步回调:当异步回调触发时,可以使用 Microtasks 来处理回调结果。

Flutter 中的 Microtasks 和 Isolate 是两个不同的概念,它们在处理并发和异步任务时起到不同的作用。

  1. Microtasks:
  • Microtasks 是 Flutter 事件循环中的一种特殊任务类型。
  • 它们会在当前事件循环周期结束前执行,优先级高于常规事件。
  • Microtasks 通常用于执行一些简单、轻量级的异步任务,比如更新 UI 状态、触发回调函数等。
  • Microtasks 是在主 Dart 隔离(Isolate)中执行的,因此它们可以直接访问 Flutter 应用程序的状态和 UI 元素。
  • 使用 Future.microtask()SchedulerBinding.instance.addMicrotask() 可以将任务添加到 Microtasks 队列中。
  1. Isolate:
  • Isolate 是 Dart 语言中的并发执行单元,类似于操作系统中的线程。
  • 每个 Isolate 都有自己的内存空间,彼此之间不共享内存,通过消息传递的方式进行通信。
  • Isolate 适用于执行 CPU 密集型或长时间运行的任务,例如图像处理、机器学习等。
  • 使用 Isolate.spawn() 可以创建新的 Isolate,并在其中执行任务。
  • Isolate 之间的通信使用 SendPortReceivePort 机制进行,这样可以避免共享内存带来的线程安全问题。

总的来说,Microtasks 与 Isolate 的主要区别如下:

  1. 执行位置:Microtasks 在主 Dart Isolate 中执行,而 Isolate 是独立的并发执行单元。
  2. 任务类型:Microtasks 适用于轻量级、快速执行的任务,而 Isolate 适用于 CPU 密集型或长时间运行的任务。
  3. 通信机制:Microtasks 直接访问应用程序状态,而 Isolate 之间通过消息传递进行通信。

小结

Flutter 作为跨平台移动应用开发框架,其异步编程能力在应用性能优化中扮演着重要角色。本文详细介绍了 Flutter 中 Future、Microtask 和并发处理的高效使用方法,包括 Future.wait、FutureBuilder 和任务分解等实用技巧,旨在帮助开发者构建出更加响应迅速、流畅的 Flutter 应用程序。

感谢阅读本文

如果有什么建议,请在评论中让我知道。我很乐意改进。


猫哥 APP

flutter 学习路径


© 猫哥 ducafecat.com

end

相关文章
|
4月前
|
Dart 前端开发 JavaScript
Flutter&Dart-异步编程Future、Stream极速入门
Flutter&Dart-异步编程Future、Stream极速入门
89 4
Flutter&Dart-异步编程Future、Stream极速入门
|
5月前
|
Dart
flutter 之 Dart 异步编程【详解】
flutter 之 Dart 异步编程【详解】
50 0
|
7月前
|
Dart 前端开发 UED
【Flutter前端技术开发专栏】深入理解Flutter中的流(Streams)和异步编程
【4月更文挑战第30天】探索Flutter的异步编程与流:了解异步编程在提升响应性和避免阻塞中的作用,掌握Stream、StreamController和StreamSubscription核心概念。通过实践案例学习如何使用流处理网络请求,提升应用性能。参考Dart和Flutter官方文档,深入理解并运用异步模式,如回调、async/await和Futures,构建更佳用户体验的Flutter应用。
103 0
【Flutter前端技术开发专栏】深入理解Flutter中的流(Streams)和异步编程
|
7月前
|
Dart 前端开发 API
【Flutter前端技术开发专栏】Flutter中的异步编程与Future/async/await
【4月更文挑战第30天】本文探讨了Flutter中的异步编程,强调其在提高应用响应性和性能上的重要性。Flutter使用`Future`对象表示异步操作的结果,通过`.then()`和`.catchError()`处理异步任务。此外,Dart的`async/await`关键字简化了异步代码,使其更易读。理解并运用这些概念对于开发高效的Flutter应用至关重要。
57 0
【Flutter前端技术开发专栏】Flutter中的异步编程与Future/async/await
|
Dart 前端开发 JavaScript
Flutter(二十二)——异步编程
Flutter(二十二)——异步编程
276 2
Flutter(二十二)——异步编程
|
Dart Java API
Flutter 异步编程原理(中)
Flutter 异步编程原理(中)
235 0
Flutter 异步编程原理(中)
|
消息中间件 Dart API
Flutter 异步编程原理(上)
Flutter 异步编程原理(上)
458 0
Flutter 异步编程原理(上)
【Flutter】Future 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )(二)
【Flutter】Future 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )(二)
725 0
【Flutter】Future 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )(二)
|
存储 Dart 安全
Flutter 异步编程原理(下)
Flutter 异步编程原理(下)
282 0
【Flutter】Future 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )(一)
【Flutter】Future 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )(一)
844 0