Flutter实战-搭建微信项目(八):异步+多线程的巧妙结合
2023-10-18 12:19:40
在上篇文章中,我们分别介绍了异步编程和多线程编程。本篇内容将带你领略异步 Future 和多线程 compute 强强联手,打造出更强大的应用场景。
异步与多线程的默契配合
先来编写一段代码,直观感受异步和多线程的结合:
import 'dart:async';
main() async {
// 模拟耗时任务
Future<String> task1 = Future.delayed(Duration(seconds: 2), () => "task1");
// 异步任务
task1.then((value) => print(value));
// 多线程任务
var task2 = await compute(calculateSum, 10, 20);
print(task2);
}
// 多线程计算任务
int calculateSum(int a, int b) {
print("task2 is running...");
return a + b;
}
运行结果如下:
task2 is running...
20
task1
可以看到,代码中同时使用了 Future(异步编程)和 compute(多线程编程)。执行顺序与我们的预期不符,compute 任务率先打印结果,而异步任务紧随其后。
解密执行顺序之谜
为何执行顺序与预期不符?原因在于:
-
异步任务被调度到了微任务队列中。 当异步任务的 then() 方法被调用时,一个新的微任务被添加到微任务队列中。微任务队列优先级高于事件队列,因此当事件循环发现微任务队列中有任务时,它会优先执行微任务。
-
多线程任务在后台线程中执行。 compute() 方法创建一个新的线程,在该线程中执行任务。主线程和后台线程是并发执行的,因此后台线程执行任务的速度可能比主线程中的微任务更快。
异步+多线程的应用场景
异步和多线程的结合在实际开发中有着广泛的应用:
-
处理耗时任务。 通过将耗时任务放到后台线程中执行,可以避免主线程卡顿,从而提升用户体验。
-
并发执行任务。 多线程可以同时执行多个任务,从而提高应用的效率。
-
异步通知。 可以通过使用 Future 来实现异步通知,当后台线程完成任务时,可以通知主线程进行后续处理。
实战演练
接下来,我们通过一个实战案例来体会异步和多线程的妙用。假设我们有一个需要耗时处理的任务,同时我们希望在任务处理过程中实时更新进度。可以使用异步和多线程来实现:
import 'dart:async';
main() async {
// 模拟耗时任务
Future<String> task = Future.delayed(Duration(seconds: 5), () => "task completed");
// 创建一个 Stream 用于更新进度
StreamController<int> progressStreamController = StreamController();
// 在后台线程中执行耗时任务,并更新进度
compute(runTask, progressStreamController).then((_) => progressStreamController.close());
// 订阅进度更新
progressStreamController.stream.listen((progress) {
print("Progress: $progress%");
});
// 当任务完成时,打印结果
task.then((value) => print(value));
}
// 在后台线程中执行任务
void runTask(StreamController<int> progressStreamController) {
for (var i = 0; i < 100; i++) {
// 模拟进度更新
progressStreamController.add(i);
// 模拟耗时任务
Future.delayed(Duration(milliseconds: 100));
}
}
运行代码,可以看到进度条实时更新,同时任务完成时打印结果。
总结
异步 Future 和多线程 compute 的巧妙结合,为 Flutter 开发提供了更强大的工具集。通过合理的应用,可以有效提升应用性能和用户体验。未来文章中,我们将深入探索异步编程和多线程编程的更多高级用法,敬请期待!