注册

跟我学flutter:我们来举个例子通俗易懂讲解异步(一)ioslate

前言


跟我学flutter系列:
跟我学flutter:我们来举个例子通俗易懂讲解dart 中的 mixin
跟我学flutter:我们来举个例子通俗易懂讲解异步(一)ioslate
跟我学flutter:我们来举个例子通俗易懂讲解异步(二)ioslate循环机制
企业级篇目:
跟我学企业级flutter项目:用bloc手把手教你搭建用户认证系统
跟我学企业级flutter项目:dio网络框架增加公共请求参数&header
跟我学企业级flutter项目:如何用dio封装一套企业级可扩展高效的网络层
跟我学企业级flutter项目:如何封装一套易用,可扩展的Hybrid混合开发webview
跟我学企业级flutter项目:手把手教你制作一款低耦合空页面widget

Dart是单线程的,Dart提供了Isolate,isolate提供了多线程的能力。但作为多线程能力的,却内存不能共享。但同样的内存不能共享,那么就不存在锁竞争问题。


举个例子来展示作用


如果一段代码执行事件很长,flutter如何开发。
基本页面代码(一段代码)


ElevatedButton(
child: Text("登录"),
onPressed: () {
执行运行代码();
}

延时代码块


String work(int value){
print("work start");
sleep(Duration(seconds:value));
print("work end");
return "work complete:$value";
}

第一种:直接执行运行代码(延时5秒)


  执行运行代码() {
work(5);
}

结果:
5秒卡的死死的


第二种:async执行运行代码(延时5秒)


  执行运行代码() async{
work(5);
}

结果:
5秒依旧卡的死死的


------------------------------------------------我是分割线--------------------------------------------------



why?在dart中,async不是异步计算么?(循环机制下篇讲)因为我们仍旧是在同一个UI线程中做运算,异步只是说我可以先运行其他的,等我这边有结果再返回,但是,我们的计算仍旧是在这个UI线程,仍会阻塞UI的刷新,异步只是在同一个线程的并发操作。



第三种:ioslate执行运行代码(延时5秒)



但是由于dart中的Isolate比较重量级,UI线程和Isolate中的数据的传输比较复杂,因此flutter为了简化用户代码,在foundation库中封装了一个轻量级compute操作。



  执行运行代码() async{
var result = await compute(work, 5);
print(result);
}

结果:
居然不卡顿了


使用说明



compute的使用还是有些限制,它没有办法多次返回结果,也没有办法持续性的传值计算,每次调用,相当于新建一个隔离,如果调用过多的话反而会适得其反。我们需要根据不同的业务选择用compute和isolate




Future work(int value) async{
//接收消息管道
ReceivePort rp = new ReceivePort();
//发送消息管道
SendPort port = rp.sendPort;
Isolate isolate = await Isolate.spawn(workEvent, port);
//发送消息管道2
final sendPort2 = await rp.first;
//返回应答数据
final answer = ReceivePort();
sendPort2.send([answer.sendPort, value]);
return answer.first;
}

void workEvent(SendPort port) {
//接收消息管道2
final rPort = ReceivePort();
SendPort port2 = rPort.sendPort;
// 将新isolate中创建的SendPort发送到主isolate中用于通信
port.send(port2);

rPort.listen((message) {
final send = message[0] as SendPort;
send.send(work(5));
});
}

基本方法


    //恢复 isolate 的使用
isolate.resume(isolate.pauseCapability);

//暂停 isolate 的使用
isolate.pause(isolate.pauseCapability);

//结束 isolate 的使用
isolate.kill(priority: Isolate.immediate);

//赋值为空 便于内存及时回收
isolate = null;


两个进程都双向绑定了消息通信的通道,即使新的Isolate中的任务完成了,它的进程也不会立刻退出,因此,当使用完自己创建的Isolate后,最好调用isolate.kill(priority: Isolate.immediate);将Isolate立即杀死。



用Future还是isolate?


future使用场景:



  • 代码段可以独立运行而不会影响应用程序的流畅性

isolate使用场景:



  • 繁重的处理可能要花一些时间才能完成
  • 网络加载大图
  • 图片处理

0 个评论

要回复文章请先登录注册