Dart 是单线程执行任务,支持异步操作
1.Isolate
2.Future
通过lsolate实现异步操作
void main() { //将消息接收器中配合的发送器传给isolate Isolate.spawn(entryPoint, "发送的消息"); Isolate.spawn(entryPoint, "发送的消息2"); Isolate.spawn(entryPoint, "发送的消息3"); print('继续运行'); } void entryPoint(String msg) { print(msg); } //运行结果 继续运行 发送的消息 发送的消息2 发送的消息3
通过Isolate 可以将一个方法进行异步执行,我们就可以在entryPoint方法中执行一些耗时任务了。
平常在android 的开发过程中,有耗时任务执行还不够,还需要线程间的交互,例如子线程请求数据在UI线程更新页面之类的,同样在Dart中我们异步Isolate 和主Isolate进行(我们暂且这样称呼)也支持数据交互。由此,接收器 ReceivePort 就出现了,顾名思义接收器就是用来接收消息的,当然有接收器 也就有发射器 SendPort,每一个接收器 都会有对应的一个发射器。
void main(){ //接收器 var receivePort = new ReceivePort(); receivePort.listen((message) { print(message); }); //发射器 var sendPort = receivePort.sendPort; sendPort.send("测试消息"); } //打印结果 测试消息
现在把Isolate 和 receivePort 结合起来使用,来完异步通信。
为了方便讲解,我们暂且分为 主lsolate和子lsolate。
既然为了通信,就需要住lsolate和子laolate 都需要持有对方的接收器,有了接收器 自然也就持有了发射器。
先将代码贴出:
void main() { late SendPort sendPort; //创建一个消息接收器 var receivePort = new ReceivePort(); //将消息接收器中配合的发送器传给isolate Isolate.spawn(entryPoint, receivePort.sendPort); //从消息接收器读取消息 receivePort.listen((message) { //判断消息类型 if (message is SendPort) { print('主线程发送器赋值'); sendPort = message; } if (message is! SendPort) { print('主线程收到的消息↓↓↓↓'); print(message); } if (message == 1) { sendPort.send("这是主线程发送给自线程的消息"); } }); print('继续运行'); } void entryPoint(SendPort sendPort) { //创建接收器 var receivePort = new ReceivePort(); receivePort.listen((message) { print('子isolate 监听到的消息' + message); }); //通过主lsolate的发送器 给主lsolate发送子lsolate的发送器 sendPort.send(receivePort.sendPort); sleep(Duration(seconds: 5)); sendPort.send("子线程发送的消息"); sleep(Duration(seconds: 5)); sendPort.send(1); }
首先创建子lsolate
然后将主lsolate 创建的接收器所对应的发射器传给子lsolate
子lsolate创建接收器,然后将这个接收器所对应的发射器发送给主lsolate
现在,主lsolate有了自己的接收器,可以接受子lsolate 的消息,有子lsolate的发射器,可以向子lsolate发送消息;子lsolate有自己的接收器,可以接收主lsolate发送的消息,也有主lsolate 的发射器,可以想主lsolate发送消息(这方面可能有点绕,需要好好梳理一下)。
至此,主lsolate 和 子lsolate 就可以进行通信了。
Future 对象表示异步操作的结果 执行异步任务,通常通过then()来处理返回的结果
void main() { Future future = Future.delayed(Duration(seconds: 3)); future.then((value) { print('异步任务'); }); print('同步任务'); } //执行结果 同步任务 异步任务
在这里是执行了延时3s的异步任务,通过结果可以看出耗时任务的执行并不会阻碍main方法的执行。
此外Future 还可进行异步任务的串联执行
void main() { Future future = Future.delayed(Duration(seconds: 3)).then((value) { print('异步任务1'); }); Future future2 = future.then((value) { sleep(Duration(seconds: 1)); print('异步任务2'); }); future2.then((value) { sleep(Duration(seconds: 1)); print('异步任务2'); }); print('同步任务'); } //执行结果 同步任务 异步任务1 异步任务2 异步任务2
async 用于标明函数是一个异步函数,其返回的对象是一个Future 对象。
await 用来等待耗时操作的返回结果,这个操作会阻塞到后面的代码。
接下里就用Future来执行一个网络请求:
void main() { print('方法开始执行'); get().then((value) { print(value); }); print('方法执行末尾'); } Future<Response> get() async { //网络访问 Response response = await Dio().get("https://www.wanandroid.com/banner/json"); return response; } //执行结果 方法开始执行 方法执行末尾 {"data":[{"des....省略
可以看出异步任务不会阻碍同步任务的执行。
最后补充一下,在Dart中提供了一种优先执行任务的任务队列:微任务队列
任务执行都是微任务队列优先
void main() { var receivePort = new ReceivePort(); receivePort.listen((message) { print(message); }); receivePort.sendPort.send("测试消息"); Future.microtask(() => { print('微任务队列'), sleep(Duration(seconds: 3)) }); } //执行结果 微任务队列 测试消息
个人笔记,仅供参考,如有问题,欢迎指正,荣幸之至。