不知道大家有没有一个疑问:Dart是单线程执行,那它是如何实现异步操作的呢?
本文将对Dart/Flutter提供的Isolate,Event Loop,Future,async/await等进行异步操作相关的知识点进行分析。
Isolate
什么是Isolate?
An isolate is what all Dart code runs in. It’s like a little space on the machine with its own, private chunk of memory and a single thread running an event loop.
- Isolate相当于
Dart语言中的线程Thread,是Dart/Flutter的执行上下文环境(容器); - Isolate有自己独立的内存地址和
Event Loop,不存在共享内存所以不会出现死锁,但是比Thread更耗内存;

- Isolate间不能直接访问,需凭借
Port进行通信;

Main Isolate
当执行完main()入口函数后,Flutter会创建一个Main Isolate。一般情况下任务都是在这个Main Isolate中执行的。
多线程
一般情况下在Main Isolate执行任务是可以接受的,但是把一些耗时操作放在Main Isolate中执行,会造成掉帧的现象,这会对用户体验造成严重影响。此时,选择将耗时任务分发到其他的Isolate中就是一个很好的实现方式了。
所有的Dart Code都是在Isolate中执行的,代码只能使用同一个Isolate中的内容,不同的 Isolate是内存隔离的,因此只能通过 Port 机制发送消息通信,其原理是向不同的 Isolate 队列中执行写任务。
案例

我们做了个简单的Demo,屏幕中间有一个心在不停的动画(由小变大,再由大变小)。当我们点击右下角对的加号按钮,会进行一个耗时的运算。如果耗时操作在Main Isolate执行,将会造成界面的丢帧,动画将会出现卡顿的情况。

我们目前就是需要解决这个掉帧的问题。
1.compute 方法
Flutter封装了一个compute这个高级API函数可以让我们方便的实现多线程的功能。
Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { String? debugLabel }) async {
}
compute接收两个必传参数:1,需要执行的方法;2,传入的参数,这参数最多只能是1个,所以多个参数需要封装到Map中;
- 最开始的代码
// 耗时操作的方法:`bigCompute`
Future<int> bigCompute(int initalNumber) async {
int total = initalNumber;
for (var i = 0; i < 1000000000; i++) {
total += i;
}
return total;
}
// 点击按钮调用的

本文深入探讨Dart如何借助Isolate实现单线程下的异步操作,包括Isolate的工作原理、EventLoop在处理Future和async/await中的作用,以及compute和直接使用Isolate的示例。通过实例解析多线程通信机制,让你理解Flutter下的异步编程策略。


被折叠的 条评论
为什么被折叠?



